925 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * ADC driver for the Ingenic JZ47xx SoCs4 * Copyright (c) 2019 Artur Rojek <contact@artur-rojek.eu>5 *6 * based on drivers/mfd/jz4740-adc.c7 */8 9#include <dt-bindings/iio/adc/ingenic,adc.h>10#include <linux/clk.h>11#include <linux/iio/buffer.h>12#include <linux/iio/iio.h>13#include <linux/interrupt.h>14#include <linux/io.h>15#include <linux/iopoll.h>16#include <linux/kernel.h>17#include <linux/module.h>18#include <linux/mod_devicetable.h>19#include <linux/mutex.h>20#include <linux/of.h>21#include <linux/platform_device.h>22#include <linux/property.h>23 24#define JZ_ADC_REG_ENABLE 0x0025#define JZ_ADC_REG_CFG 0x0426#define JZ_ADC_REG_CTRL 0x0827#define JZ_ADC_REG_STATUS 0x0c28#define JZ_ADC_REG_ADSAME 0x1029#define JZ_ADC_REG_ADWAIT 0x1430#define JZ_ADC_REG_ADTCH 0x1831#define JZ_ADC_REG_ADBDAT 0x1c32#define JZ_ADC_REG_ADSDAT 0x2033#define JZ_ADC_REG_ADCMD 0x2434#define JZ_ADC_REG_ADCLK 0x2835 36#define JZ_ADC_REG_ENABLE_PD BIT(7)37#define JZ_ADC_REG_CFG_AUX_MD (BIT(0) | BIT(1))38#define JZ_ADC_REG_CFG_BAT_MD BIT(4)39#define JZ_ADC_REG_CFG_SAMPLE_NUM(n) ((n) << 10)40#define JZ_ADC_REG_CFG_PULL_UP(n) ((n) << 16)41#define JZ_ADC_REG_CFG_CMD_SEL BIT(22)42#define JZ_ADC_REG_CFG_VBAT_SEL BIT(30)43#define JZ_ADC_REG_CFG_TOUCH_OPS_MASK (BIT(31) | GENMASK(23, 10))44#define JZ_ADC_REG_ADCLK_CLKDIV_LSB 045#define JZ4725B_ADC_REG_ADCLK_CLKDIV10US_LSB 1646#define JZ4770_ADC_REG_ADCLK_CLKDIV10US_LSB 847#define JZ4770_ADC_REG_ADCLK_CLKDIVMS_LSB 1648 49#define JZ_ADC_REG_ADCMD_YNADC BIT(7)50#define JZ_ADC_REG_ADCMD_YPADC BIT(8)51#define JZ_ADC_REG_ADCMD_XNADC BIT(9)52#define JZ_ADC_REG_ADCMD_XPADC BIT(10)53#define JZ_ADC_REG_ADCMD_VREFPYP BIT(11)54#define JZ_ADC_REG_ADCMD_VREFPXP BIT(12)55#define JZ_ADC_REG_ADCMD_VREFPXN BIT(13)56#define JZ_ADC_REG_ADCMD_VREFPAUX BIT(14)57#define JZ_ADC_REG_ADCMD_VREFPVDD33 BIT(15)58#define JZ_ADC_REG_ADCMD_VREFNYN BIT(16)59#define JZ_ADC_REG_ADCMD_VREFNXP BIT(17)60#define JZ_ADC_REG_ADCMD_VREFNXN BIT(18)61#define JZ_ADC_REG_ADCMD_VREFAUX BIT(19)62#define JZ_ADC_REG_ADCMD_YNGRU BIT(20)63#define JZ_ADC_REG_ADCMD_XNGRU BIT(21)64#define JZ_ADC_REG_ADCMD_XPGRU BIT(22)65#define JZ_ADC_REG_ADCMD_YPSUP BIT(23)66#define JZ_ADC_REG_ADCMD_XNSUP BIT(24)67#define JZ_ADC_REG_ADCMD_XPSUP BIT(25)68 69#define JZ_ADC_AUX_VREF 330070#define JZ_ADC_AUX_VREF_BITS 1271#define JZ_ADC_BATTERY_LOW_VREF 250072#define JZ_ADC_BATTERY_LOW_VREF_BITS 1273#define JZ4725B_ADC_BATTERY_HIGH_VREF 750074#define JZ4725B_ADC_BATTERY_HIGH_VREF_BITS 1075#define JZ4740_ADC_BATTERY_HIGH_VREF (7500 * 0.986)76#define JZ4740_ADC_BATTERY_HIGH_VREF_BITS 1277#define JZ4760_ADC_BATTERY_VREF 250078#define JZ4770_ADC_BATTERY_VREF 120079#define JZ4770_ADC_BATTERY_VREF_BITS 1280 81#define JZ_ADC_IRQ_AUX BIT(0)82#define JZ_ADC_IRQ_BATTERY BIT(1)83#define JZ_ADC_IRQ_TOUCH BIT(2)84#define JZ_ADC_IRQ_PEN_DOWN BIT(3)85#define JZ_ADC_IRQ_PEN_UP BIT(4)86#define JZ_ADC_IRQ_PEN_DOWN_SLEEP BIT(5)87#define JZ_ADC_IRQ_SLEEP BIT(7)88 89struct ingenic_adc;90 91struct ingenic_adc_soc_data {92 unsigned int battery_high_vref;93 unsigned int battery_high_vref_bits;94 const int *battery_raw_avail;95 size_t battery_raw_avail_size;96 const int *battery_scale_avail;97 size_t battery_scale_avail_size;98 unsigned int battery_vref_mode: 1;99 unsigned int has_aux_md: 1;100 const struct iio_chan_spec *channels;101 unsigned int num_channels;102 int (*init_clk_div)(struct device *dev, struct ingenic_adc *adc);103};104 105struct ingenic_adc {106 void __iomem *base;107 struct clk *clk;108 struct mutex lock;109 struct mutex aux_lock;110 const struct ingenic_adc_soc_data *soc_data;111 bool low_vref_mode;112};113 114static void ingenic_adc_set_adcmd(struct iio_dev *iio_dev, unsigned long mask)115{116 struct ingenic_adc *adc = iio_priv(iio_dev);117 118 mutex_lock(&adc->lock);119 120 /* Init ADCMD */121 readl(adc->base + JZ_ADC_REG_ADCMD);122 123 if (mask & 0x3) {124 /* Second channel (INGENIC_ADC_TOUCH_YP): sample YP vs. GND */125 writel(JZ_ADC_REG_ADCMD_XNGRU126 | JZ_ADC_REG_ADCMD_VREFNXN | JZ_ADC_REG_ADCMD_VREFPVDD33127 | JZ_ADC_REG_ADCMD_YPADC,128 adc->base + JZ_ADC_REG_ADCMD);129 130 /* First channel (INGENIC_ADC_TOUCH_XP): sample XP vs. GND */131 writel(JZ_ADC_REG_ADCMD_YNGRU132 | JZ_ADC_REG_ADCMD_VREFNYN | JZ_ADC_REG_ADCMD_VREFPVDD33133 | JZ_ADC_REG_ADCMD_XPADC,134 adc->base + JZ_ADC_REG_ADCMD);135 }136 137 if (mask & 0xc) {138 /* Fourth channel (INGENIC_ADC_TOUCH_YN): sample YN vs. GND */139 writel(JZ_ADC_REG_ADCMD_XNGRU140 | JZ_ADC_REG_ADCMD_VREFNXN | JZ_ADC_REG_ADCMD_VREFPVDD33141 | JZ_ADC_REG_ADCMD_YNADC,142 adc->base + JZ_ADC_REG_ADCMD);143 144 /* Third channel (INGENIC_ADC_TOUCH_XN): sample XN vs. GND */145 writel(JZ_ADC_REG_ADCMD_YNGRU146 | JZ_ADC_REG_ADCMD_VREFNYN | JZ_ADC_REG_ADCMD_VREFPVDD33147 | JZ_ADC_REG_ADCMD_XNADC,148 adc->base + JZ_ADC_REG_ADCMD);149 }150 151 if (mask & 0x30) {152 /* Sixth channel (INGENIC_ADC_TOUCH_YD): sample YP vs. YN */153 writel(JZ_ADC_REG_ADCMD_VREFNYN | JZ_ADC_REG_ADCMD_VREFPVDD33154 | JZ_ADC_REG_ADCMD_YPADC,155 adc->base + JZ_ADC_REG_ADCMD);156 157 /* Fifth channel (INGENIC_ADC_TOUCH_XD): sample XP vs. XN */158 writel(JZ_ADC_REG_ADCMD_VREFNXN | JZ_ADC_REG_ADCMD_VREFPVDD33159 | JZ_ADC_REG_ADCMD_XPADC,160 adc->base + JZ_ADC_REG_ADCMD);161 }162 163 /* We're done */164 writel(0, adc->base + JZ_ADC_REG_ADCMD);165 166 mutex_unlock(&adc->lock);167}168 169static void ingenic_adc_set_config(struct ingenic_adc *adc,170 uint32_t mask,171 uint32_t val)172{173 uint32_t cfg;174 175 mutex_lock(&adc->lock);176 177 cfg = readl(adc->base + JZ_ADC_REG_CFG) & ~mask;178 cfg |= val;179 writel(cfg, adc->base + JZ_ADC_REG_CFG);180 181 mutex_unlock(&adc->lock);182}183 184static void ingenic_adc_enable_unlocked(struct ingenic_adc *adc,185 int engine,186 bool enabled)187{188 u8 val;189 190 val = readb(adc->base + JZ_ADC_REG_ENABLE);191 192 if (enabled)193 val |= BIT(engine);194 else195 val &= ~BIT(engine);196 197 writeb(val, adc->base + JZ_ADC_REG_ENABLE);198}199 200static void ingenic_adc_enable(struct ingenic_adc *adc,201 int engine,202 bool enabled)203{204 mutex_lock(&adc->lock);205 ingenic_adc_enable_unlocked(adc, engine, enabled);206 mutex_unlock(&adc->lock);207}208 209static int ingenic_adc_capture(struct ingenic_adc *adc,210 int engine)211{212 u32 cfg;213 u8 val;214 int ret;215 216 /*217 * Disable CMD_SEL temporarily, because it causes wrong VBAT readings,218 * probably due to the switch of VREF. We must keep the lock here to219 * avoid races with the buffer enable/disable functions.220 */221 mutex_lock(&adc->lock);222 cfg = readl(adc->base + JZ_ADC_REG_CFG);223 writel(cfg & ~JZ_ADC_REG_CFG_CMD_SEL, adc->base + JZ_ADC_REG_CFG);224 225 ingenic_adc_enable_unlocked(adc, engine, true);226 ret = readb_poll_timeout(adc->base + JZ_ADC_REG_ENABLE, val,227 !(val & BIT(engine)), 250, 1000);228 if (ret)229 ingenic_adc_enable_unlocked(adc, engine, false);230 231 writel(cfg, adc->base + JZ_ADC_REG_CFG);232 mutex_unlock(&adc->lock);233 234 return ret;235}236 237static int ingenic_adc_write_raw(struct iio_dev *iio_dev,238 struct iio_chan_spec const *chan,239 int val,240 int val2,241 long m)242{243 struct ingenic_adc *adc = iio_priv(iio_dev);244 struct device *dev = iio_dev->dev.parent;245 int ret;246 247 switch (m) {248 case IIO_CHAN_INFO_SCALE:249 switch (chan->channel) {250 case INGENIC_ADC_BATTERY:251 if (!adc->soc_data->battery_vref_mode)252 return -EINVAL;253 254 ret = clk_enable(adc->clk);255 if (ret) {256 dev_err(dev, "Failed to enable clock: %d\n",257 ret);258 return ret;259 }260 261 if (val > JZ_ADC_BATTERY_LOW_VREF) {262 ingenic_adc_set_config(adc,263 JZ_ADC_REG_CFG_BAT_MD,264 0);265 adc->low_vref_mode = false;266 } else {267 ingenic_adc_set_config(adc,268 JZ_ADC_REG_CFG_BAT_MD,269 JZ_ADC_REG_CFG_BAT_MD);270 adc->low_vref_mode = true;271 }272 273 clk_disable(adc->clk);274 275 return 0;276 default:277 return -EINVAL;278 }279 default:280 return -EINVAL;281 }282}283 284static const int jz4725b_adc_battery_raw_avail[] = {285 0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1,286};287 288static const int jz4725b_adc_battery_scale_avail[] = {289 JZ4725B_ADC_BATTERY_HIGH_VREF, JZ4725B_ADC_BATTERY_HIGH_VREF_BITS,290 JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS,291};292 293static const int jz4740_adc_battery_raw_avail[] = {294 0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1,295};296 297static const int jz4740_adc_battery_scale_avail[] = {298 JZ4740_ADC_BATTERY_HIGH_VREF, JZ4740_ADC_BATTERY_HIGH_VREF_BITS,299 JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS,300};301 302static const int jz4760_adc_battery_scale_avail[] = {303 JZ4760_ADC_BATTERY_VREF, JZ4770_ADC_BATTERY_VREF_BITS,304};305 306static const int jz4770_adc_battery_raw_avail[] = {307 0, 1, (1 << JZ4770_ADC_BATTERY_VREF_BITS) - 1,308};309 310static const int jz4770_adc_battery_scale_avail[] = {311 JZ4770_ADC_BATTERY_VREF, JZ4770_ADC_BATTERY_VREF_BITS,312};313 314static int jz4725b_adc_init_clk_div(struct device *dev, struct ingenic_adc *adc)315{316 struct clk *parent_clk;317 unsigned long parent_rate, rate;318 unsigned int div_main, div_10us;319 320 parent_clk = clk_get_parent(adc->clk);321 if (!parent_clk) {322 dev_err(dev, "ADC clock has no parent\n");323 return -ENODEV;324 }325 parent_rate = clk_get_rate(parent_clk);326 327 /*328 * The JZ4725B ADC works at 500 kHz to 8 MHz.329 * We pick the highest rate possible.330 * In practice we typically get 6 MHz, half of the 12 MHz EXT clock.331 */332 div_main = DIV_ROUND_UP(parent_rate, 8000000);333 div_main = clamp(div_main, 1u, 64u);334 rate = parent_rate / div_main;335 if (rate < 500000 || rate > 8000000) {336 dev_err(dev, "No valid divider for ADC main clock\n");337 return -EINVAL;338 }339 340 /* We also need a divider that produces a 10us clock. */341 div_10us = DIV_ROUND_UP(rate, 100000);342 343 writel(((div_10us - 1) << JZ4725B_ADC_REG_ADCLK_CLKDIV10US_LSB) |344 (div_main - 1) << JZ_ADC_REG_ADCLK_CLKDIV_LSB,345 adc->base + JZ_ADC_REG_ADCLK);346 347 return 0;348}349 350static int jz4770_adc_init_clk_div(struct device *dev, struct ingenic_adc *adc)351{352 struct clk *parent_clk;353 unsigned long parent_rate, rate;354 unsigned int div_main, div_ms, div_10us;355 356 parent_clk = clk_get_parent(adc->clk);357 if (!parent_clk) {358 dev_err(dev, "ADC clock has no parent\n");359 return -ENODEV;360 }361 parent_rate = clk_get_rate(parent_clk);362 363 /*364 * The JZ4770 ADC works at 20 kHz to 200 kHz.365 * We pick the highest rate possible.366 */367 div_main = DIV_ROUND_UP(parent_rate, 200000);368 div_main = clamp(div_main, 1u, 256u);369 rate = parent_rate / div_main;370 if (rate < 20000 || rate > 200000) {371 dev_err(dev, "No valid divider for ADC main clock\n");372 return -EINVAL;373 }374 375 /* We also need a divider that produces a 10us clock. */376 div_10us = DIV_ROUND_UP(rate, 10000);377 /* And another, which produces a 1ms clock. */378 div_ms = DIV_ROUND_UP(rate, 1000);379 380 writel(((div_ms - 1) << JZ4770_ADC_REG_ADCLK_CLKDIVMS_LSB) |381 ((div_10us - 1) << JZ4770_ADC_REG_ADCLK_CLKDIV10US_LSB) |382 (div_main - 1) << JZ_ADC_REG_ADCLK_CLKDIV_LSB,383 adc->base + JZ_ADC_REG_ADCLK);384 385 return 0;386}387 388static const struct iio_chan_spec jz4740_channels[] = {389 {390 .extend_name = "aux",391 .type = IIO_VOLTAGE,392 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |393 BIT(IIO_CHAN_INFO_SCALE),394 .indexed = 1,395 .channel = INGENIC_ADC_AUX,396 .scan_index = -1,397 },398 {399 .extend_name = "battery",400 .type = IIO_VOLTAGE,401 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |402 BIT(IIO_CHAN_INFO_SCALE),403 .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |404 BIT(IIO_CHAN_INFO_SCALE),405 .indexed = 1,406 .channel = INGENIC_ADC_BATTERY,407 .scan_index = -1,408 },409};410 411static const struct iio_chan_spec jz4760_channels[] = {412 {413 .extend_name = "aux",414 .type = IIO_VOLTAGE,415 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |416 BIT(IIO_CHAN_INFO_SCALE),417 .indexed = 1,418 .channel = INGENIC_ADC_AUX0,419 .scan_index = -1,420 },421 {422 .extend_name = "aux1",423 .type = IIO_VOLTAGE,424 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |425 BIT(IIO_CHAN_INFO_SCALE),426 .indexed = 1,427 .channel = INGENIC_ADC_AUX,428 .scan_index = -1,429 },430 {431 .extend_name = "aux2",432 .type = IIO_VOLTAGE,433 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |434 BIT(IIO_CHAN_INFO_SCALE),435 .indexed = 1,436 .channel = INGENIC_ADC_AUX2,437 .scan_index = -1,438 },439 {440 .extend_name = "battery",441 .type = IIO_VOLTAGE,442 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |443 BIT(IIO_CHAN_INFO_SCALE),444 .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |445 BIT(IIO_CHAN_INFO_SCALE),446 .indexed = 1,447 .channel = INGENIC_ADC_BATTERY,448 .scan_index = -1,449 },450};451 452static const struct iio_chan_spec jz4770_channels[] = {453 {454 .type = IIO_VOLTAGE,455 .indexed = 1,456 .channel = INGENIC_ADC_TOUCH_XP,457 .scan_index = 0,458 .scan_type = {459 .sign = 'u',460 .realbits = 12,461 .storagebits = 16,462 },463 },464 {465 .type = IIO_VOLTAGE,466 .indexed = 1,467 .channel = INGENIC_ADC_TOUCH_YP,468 .scan_index = 1,469 .scan_type = {470 .sign = 'u',471 .realbits = 12,472 .storagebits = 16,473 },474 },475 {476 .type = IIO_VOLTAGE,477 .indexed = 1,478 .channel = INGENIC_ADC_TOUCH_XN,479 .scan_index = 2,480 .scan_type = {481 .sign = 'u',482 .realbits = 12,483 .storagebits = 16,484 },485 },486 {487 .type = IIO_VOLTAGE,488 .indexed = 1,489 .channel = INGENIC_ADC_TOUCH_YN,490 .scan_index = 3,491 .scan_type = {492 .sign = 'u',493 .realbits = 12,494 .storagebits = 16,495 },496 },497 {498 .type = IIO_VOLTAGE,499 .indexed = 1,500 .channel = INGENIC_ADC_TOUCH_XD,501 .scan_index = 4,502 .scan_type = {503 .sign = 'u',504 .realbits = 12,505 .storagebits = 16,506 },507 },508 {509 .type = IIO_VOLTAGE,510 .indexed = 1,511 .channel = INGENIC_ADC_TOUCH_YD,512 .scan_index = 5,513 .scan_type = {514 .sign = 'u',515 .realbits = 12,516 .storagebits = 16,517 },518 },519 {520 .extend_name = "aux",521 .type = IIO_VOLTAGE,522 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |523 BIT(IIO_CHAN_INFO_SCALE),524 .indexed = 1,525 .channel = INGENIC_ADC_AUX,526 .scan_index = -1,527 },528 {529 .extend_name = "battery",530 .type = IIO_VOLTAGE,531 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |532 BIT(IIO_CHAN_INFO_SCALE),533 .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |534 BIT(IIO_CHAN_INFO_SCALE),535 .indexed = 1,536 .channel = INGENIC_ADC_BATTERY,537 .scan_index = -1,538 },539 {540 .extend_name = "aux2",541 .type = IIO_VOLTAGE,542 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |543 BIT(IIO_CHAN_INFO_SCALE),544 .indexed = 1,545 .channel = INGENIC_ADC_AUX2,546 .scan_index = -1,547 },548};549 550static const struct ingenic_adc_soc_data jz4725b_adc_soc_data = {551 .battery_high_vref = JZ4725B_ADC_BATTERY_HIGH_VREF,552 .battery_high_vref_bits = JZ4725B_ADC_BATTERY_HIGH_VREF_BITS,553 .battery_raw_avail = jz4725b_adc_battery_raw_avail,554 .battery_raw_avail_size = ARRAY_SIZE(jz4725b_adc_battery_raw_avail),555 .battery_scale_avail = jz4725b_adc_battery_scale_avail,556 .battery_scale_avail_size = ARRAY_SIZE(jz4725b_adc_battery_scale_avail),557 .battery_vref_mode = true,558 .has_aux_md = false,559 .channels = jz4740_channels,560 .num_channels = ARRAY_SIZE(jz4740_channels),561 .init_clk_div = jz4725b_adc_init_clk_div,562};563 564static const struct ingenic_adc_soc_data jz4740_adc_soc_data = {565 .battery_high_vref = JZ4740_ADC_BATTERY_HIGH_VREF,566 .battery_high_vref_bits = JZ4740_ADC_BATTERY_HIGH_VREF_BITS,567 .battery_raw_avail = jz4740_adc_battery_raw_avail,568 .battery_raw_avail_size = ARRAY_SIZE(jz4740_adc_battery_raw_avail),569 .battery_scale_avail = jz4740_adc_battery_scale_avail,570 .battery_scale_avail_size = ARRAY_SIZE(jz4740_adc_battery_scale_avail),571 .battery_vref_mode = true,572 .has_aux_md = false,573 .channels = jz4740_channels,574 .num_channels = ARRAY_SIZE(jz4740_channels),575 .init_clk_div = NULL, /* no ADCLK register on JZ4740 */576};577 578static const struct ingenic_adc_soc_data jz4760_adc_soc_data = {579 .battery_high_vref = JZ4760_ADC_BATTERY_VREF,580 .battery_high_vref_bits = JZ4770_ADC_BATTERY_VREF_BITS,581 .battery_raw_avail = jz4770_adc_battery_raw_avail,582 .battery_raw_avail_size = ARRAY_SIZE(jz4770_adc_battery_raw_avail),583 .battery_scale_avail = jz4760_adc_battery_scale_avail,584 .battery_scale_avail_size = ARRAY_SIZE(jz4760_adc_battery_scale_avail),585 .battery_vref_mode = false,586 .has_aux_md = true,587 .channels = jz4760_channels,588 .num_channels = ARRAY_SIZE(jz4760_channels),589 .init_clk_div = jz4770_adc_init_clk_div,590};591 592static const struct ingenic_adc_soc_data jz4770_adc_soc_data = {593 .battery_high_vref = JZ4770_ADC_BATTERY_VREF,594 .battery_high_vref_bits = JZ4770_ADC_BATTERY_VREF_BITS,595 .battery_raw_avail = jz4770_adc_battery_raw_avail,596 .battery_raw_avail_size = ARRAY_SIZE(jz4770_adc_battery_raw_avail),597 .battery_scale_avail = jz4770_adc_battery_scale_avail,598 .battery_scale_avail_size = ARRAY_SIZE(jz4770_adc_battery_scale_avail),599 .battery_vref_mode = false,600 .has_aux_md = true,601 .channels = jz4770_channels,602 .num_channels = ARRAY_SIZE(jz4770_channels),603 .init_clk_div = jz4770_adc_init_clk_div,604};605 606static int ingenic_adc_read_avail(struct iio_dev *iio_dev,607 struct iio_chan_spec const *chan,608 const int **vals,609 int *type,610 int *length,611 long m)612{613 struct ingenic_adc *adc = iio_priv(iio_dev);614 615 switch (m) {616 case IIO_CHAN_INFO_RAW:617 *type = IIO_VAL_INT;618 *length = adc->soc_data->battery_raw_avail_size;619 *vals = adc->soc_data->battery_raw_avail;620 return IIO_AVAIL_RANGE;621 case IIO_CHAN_INFO_SCALE:622 *type = IIO_VAL_FRACTIONAL_LOG2;623 *length = adc->soc_data->battery_scale_avail_size;624 *vals = adc->soc_data->battery_scale_avail;625 return IIO_AVAIL_LIST;626 default:627 return -EINVAL;628 }629}630 631static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,632 struct iio_chan_spec const *chan,633 int *val)634{635 int cmd, ret, engine = (chan->channel == INGENIC_ADC_BATTERY);636 struct ingenic_adc *adc = iio_priv(iio_dev);637 638 ret = clk_enable(adc->clk);639 if (ret) {640 dev_err(iio_dev->dev.parent, "Failed to enable clock: %d\n",641 ret);642 return ret;643 }644 645 /* We cannot sample the aux channels in parallel. */646 mutex_lock(&adc->aux_lock);647 if (adc->soc_data->has_aux_md && engine == 0) {648 switch (chan->channel) {649 case INGENIC_ADC_AUX0:650 cmd = 0;651 break;652 case INGENIC_ADC_AUX:653 cmd = 1;654 break;655 case INGENIC_ADC_AUX2:656 cmd = 2;657 break;658 }659 660 ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_AUX_MD, cmd);661 }662 663 ret = ingenic_adc_capture(adc, engine);664 if (ret)665 goto out;666 667 switch (chan->channel) {668 case INGENIC_ADC_AUX0:669 case INGENIC_ADC_AUX:670 case INGENIC_ADC_AUX2:671 *val = readw(adc->base + JZ_ADC_REG_ADSDAT);672 break;673 case INGENIC_ADC_BATTERY:674 *val = readw(adc->base + JZ_ADC_REG_ADBDAT);675 break;676 }677 678 ret = IIO_VAL_INT;679out:680 mutex_unlock(&adc->aux_lock);681 clk_disable(adc->clk);682 683 return ret;684}685 686static int ingenic_adc_read_raw(struct iio_dev *iio_dev,687 struct iio_chan_spec const *chan,688 int *val,689 int *val2,690 long m)691{692 struct ingenic_adc *adc = iio_priv(iio_dev);693 694 switch (m) {695 case IIO_CHAN_INFO_RAW:696 return ingenic_adc_read_chan_info_raw(iio_dev, chan, val);697 case IIO_CHAN_INFO_SCALE:698 switch (chan->channel) {699 case INGENIC_ADC_AUX0:700 case INGENIC_ADC_AUX:701 case INGENIC_ADC_AUX2:702 *val = JZ_ADC_AUX_VREF;703 *val2 = JZ_ADC_AUX_VREF_BITS;704 break;705 case INGENIC_ADC_BATTERY:706 if (adc->low_vref_mode) {707 *val = JZ_ADC_BATTERY_LOW_VREF;708 *val2 = JZ_ADC_BATTERY_LOW_VREF_BITS;709 } else {710 *val = adc->soc_data->battery_high_vref;711 *val2 = adc->soc_data->battery_high_vref_bits;712 }713 break;714 }715 716 return IIO_VAL_FRACTIONAL_LOG2;717 default:718 return -EINVAL;719 }720}721 722static int ingenic_adc_fwnode_xlate(struct iio_dev *iio_dev,723 const struct fwnode_reference_args *iiospec)724{725 int i;726 727 if (!iiospec->nargs)728 return -EINVAL;729 730 for (i = 0; i < iio_dev->num_channels; ++i)731 if (iio_dev->channels[i].channel == iiospec->args[0])732 return i;733 734 return -EINVAL;735}736 737static const struct iio_info ingenic_adc_info = {738 .write_raw = ingenic_adc_write_raw,739 .read_raw = ingenic_adc_read_raw,740 .read_avail = ingenic_adc_read_avail,741 .fwnode_xlate = ingenic_adc_fwnode_xlate,742};743 744static int ingenic_adc_buffer_enable(struct iio_dev *iio_dev)745{746 struct ingenic_adc *adc = iio_priv(iio_dev);747 int ret;748 749 ret = clk_enable(adc->clk);750 if (ret) {751 dev_err(iio_dev->dev.parent, "Failed to enable clock: %d\n",752 ret);753 return ret;754 }755 756 /* It takes significant time for the touchscreen hw to stabilize. */757 msleep(50);758 ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_TOUCH_OPS_MASK,759 JZ_ADC_REG_CFG_SAMPLE_NUM(4) |760 JZ_ADC_REG_CFG_PULL_UP(4));761 762 writew(80, adc->base + JZ_ADC_REG_ADWAIT);763 writew(2, adc->base + JZ_ADC_REG_ADSAME);764 writeb((u8)~JZ_ADC_IRQ_TOUCH, adc->base + JZ_ADC_REG_CTRL);765 writel(0, adc->base + JZ_ADC_REG_ADTCH);766 767 ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_CMD_SEL,768 JZ_ADC_REG_CFG_CMD_SEL);769 ingenic_adc_set_adcmd(iio_dev, iio_dev->active_scan_mask[0]);770 771 ingenic_adc_enable(adc, 2, true);772 773 return 0;774}775 776static int ingenic_adc_buffer_disable(struct iio_dev *iio_dev)777{778 struct ingenic_adc *adc = iio_priv(iio_dev);779 780 ingenic_adc_enable(adc, 2, false);781 782 ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_CMD_SEL, 0);783 784 writeb(0xff, adc->base + JZ_ADC_REG_CTRL);785 writeb(0xff, adc->base + JZ_ADC_REG_STATUS);786 ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_TOUCH_OPS_MASK, 0);787 writew(0, adc->base + JZ_ADC_REG_ADSAME);788 writew(0, adc->base + JZ_ADC_REG_ADWAIT);789 clk_disable(adc->clk);790 791 return 0;792}793 794static const struct iio_buffer_setup_ops ingenic_buffer_setup_ops = {795 .postenable = &ingenic_adc_buffer_enable,796 .predisable = &ingenic_adc_buffer_disable797};798 799static irqreturn_t ingenic_adc_irq(int irq, void *data)800{801 struct iio_dev *iio_dev = data;802 struct ingenic_adc *adc = iio_priv(iio_dev);803 unsigned long mask = iio_dev->active_scan_mask[0];804 unsigned int i;805 u32 tdat[3];806 807 for (i = 0; i < ARRAY_SIZE(tdat); mask >>= 2, i++) {808 if (mask & 0x3)809 tdat[i] = readl(adc->base + JZ_ADC_REG_ADTCH);810 else811 tdat[i] = 0;812 }813 814 iio_push_to_buffers(iio_dev, tdat);815 writeb(JZ_ADC_IRQ_TOUCH, adc->base + JZ_ADC_REG_STATUS);816 817 return IRQ_HANDLED;818}819 820static int ingenic_adc_probe(struct platform_device *pdev)821{822 struct device *dev = &pdev->dev;823 struct iio_dev *iio_dev;824 struct ingenic_adc *adc;825 const struct ingenic_adc_soc_data *soc_data;826 int irq, ret;827 828 soc_data = device_get_match_data(dev);829 if (!soc_data)830 return -EINVAL;831 832 iio_dev = devm_iio_device_alloc(dev, sizeof(*adc));833 if (!iio_dev)834 return -ENOMEM;835 836 adc = iio_priv(iio_dev);837 mutex_init(&adc->lock);838 mutex_init(&adc->aux_lock);839 adc->soc_data = soc_data;840 841 irq = platform_get_irq(pdev, 0);842 if (irq < 0)843 return irq;844 845 ret = devm_request_irq(dev, irq, ingenic_adc_irq, 0,846 dev_name(dev), iio_dev);847 if (ret < 0) {848 dev_err(dev, "Failed to request irq: %d\n", ret);849 return ret;850 }851 852 adc->base = devm_platform_ioremap_resource(pdev, 0);853 if (IS_ERR(adc->base))854 return PTR_ERR(adc->base);855 856 adc->clk = devm_clk_get_prepared(dev, "adc");857 if (IS_ERR(adc->clk)) {858 dev_err(dev, "Unable to get clock\n");859 return PTR_ERR(adc->clk);860 }861 862 ret = clk_enable(adc->clk);863 if (ret) {864 dev_err(dev, "Failed to enable clock\n");865 return ret;866 }867 868 /* Set clock dividers. */869 if (soc_data->init_clk_div) {870 ret = soc_data->init_clk_div(dev, adc);871 if (ret) {872 clk_disable_unprepare(adc->clk);873 return ret;874 }875 }876 877 /* Put hardware in a known passive state. */878 writeb(0x00, adc->base + JZ_ADC_REG_ENABLE);879 writeb(0xff, adc->base + JZ_ADC_REG_CTRL);880 881 /* JZ4760B specific */882 if (device_property_present(dev, "ingenic,use-internal-divider"))883 ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_VBAT_SEL,884 JZ_ADC_REG_CFG_VBAT_SEL);885 else886 ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_VBAT_SEL, 0);887 888 usleep_range(2000, 3000); /* Must wait at least 2ms. */889 clk_disable(adc->clk);890 891 iio_dev->name = "jz-adc";892 iio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;893 iio_dev->setup_ops = &ingenic_buffer_setup_ops;894 iio_dev->channels = soc_data->channels;895 iio_dev->num_channels = soc_data->num_channels;896 iio_dev->info = &ingenic_adc_info;897 898 ret = devm_iio_device_register(dev, iio_dev);899 if (ret)900 dev_err(dev, "Unable to register IIO device\n");901 902 return ret;903}904 905static const struct of_device_id ingenic_adc_of_match[] = {906 { .compatible = "ingenic,jz4725b-adc", .data = &jz4725b_adc_soc_data, },907 { .compatible = "ingenic,jz4740-adc", .data = &jz4740_adc_soc_data, },908 { .compatible = "ingenic,jz4760-adc", .data = &jz4760_adc_soc_data, },909 { .compatible = "ingenic,jz4760b-adc", .data = &jz4760_adc_soc_data, },910 { .compatible = "ingenic,jz4770-adc", .data = &jz4770_adc_soc_data, },911 { }912};913MODULE_DEVICE_TABLE(of, ingenic_adc_of_match);914 915static struct platform_driver ingenic_adc_driver = {916 .driver = {917 .name = "ingenic-adc",918 .of_match_table = ingenic_adc_of_match,919 },920 .probe = ingenic_adc_probe,921};922module_platform_driver(ingenic_adc_driver);923MODULE_DESCRIPTION("ADC driver for the Ingenic JZ47xx SoCs");924MODULE_LICENSE("GPL v2");925