0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/platform_device.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/device.h>
0012 #include <linux/kernel.h>
0013 #include <linux/slab.h>
0014 #include <linux/io.h>
0015 #include <linux/clk.h>
0016 #include <linux/err.h>
0017 #include <linux/completion.h>
0018 #include <linux/of.h>
0019 #include <linux/of_address.h>
0020
0021 #include <linux/iio/iio.h>
0022 #include <linux/iio/sysfs.h>
0023
0024
0025 #define SPEAR600_ADC_SCAN_RATE_LO(x) ((x) & 0xFFFF)
0026 #define SPEAR600_ADC_SCAN_RATE_HI(x) (((x) >> 0x10) & 0xFFFF)
0027 #define SPEAR_ADC_CLK_LOW(x) (((x) & 0xf) << 0)
0028 #define SPEAR_ADC_CLK_HIGH(x) (((x) & 0xf) << 4)
0029
0030
0031 #define SPEAR_ADC_STATUS_START_CONVERSION BIT(0)
0032 #define SPEAR_ADC_STATUS_CHANNEL_NUM(x) ((x) << 1)
0033 #define SPEAR_ADC_STATUS_ADC_ENABLE BIT(4)
0034 #define SPEAR_ADC_STATUS_AVG_SAMPLE(x) ((x) << 5)
0035 #define SPEAR_ADC_STATUS_VREF_INTERNAL BIT(9)
0036
0037 #define SPEAR_ADC_DATA_MASK 0x03ff
0038 #define SPEAR_ADC_DATA_BITS 10
0039
0040 #define SPEAR_ADC_MOD_NAME "spear-adc"
0041
0042 #define SPEAR_ADC_CHANNEL_NUM 8
0043
0044 #define SPEAR_ADC_CLK_MIN 2500000
0045 #define SPEAR_ADC_CLK_MAX 20000000
0046
0047 struct adc_regs_spear3xx {
0048 u32 status;
0049 u32 average;
0050 u32 scan_rate;
0051 u32 clk;
0052 u32 ch_ctrl[SPEAR_ADC_CHANNEL_NUM];
0053 u32 ch_data[SPEAR_ADC_CHANNEL_NUM];
0054 };
0055
0056 struct chan_data {
0057 u32 lsb;
0058 u32 msb;
0059 };
0060
0061 struct adc_regs_spear6xx {
0062 u32 status;
0063 u32 pad[2];
0064 u32 clk;
0065 u32 ch_ctrl[SPEAR_ADC_CHANNEL_NUM];
0066 struct chan_data ch_data[SPEAR_ADC_CHANNEL_NUM];
0067 u32 scan_rate_lo;
0068 u32 scan_rate_hi;
0069 struct chan_data average;
0070 };
0071
0072 struct spear_adc_state {
0073 struct device_node *np;
0074 struct adc_regs_spear3xx __iomem *adc_base_spear3xx;
0075 struct adc_regs_spear6xx __iomem *adc_base_spear6xx;
0076 struct clk *clk;
0077 struct completion completion;
0078
0079
0080
0081
0082
0083
0084
0085
0086 struct mutex lock;
0087 u32 current_clk;
0088 u32 sampling_freq;
0089 u32 avg_samples;
0090 u32 vref_external;
0091 u32 value;
0092 };
0093
0094
0095
0096
0097
0098
0099 static void spear_adc_set_status(struct spear_adc_state *st, u32 val)
0100 {
0101 __raw_writel(val, &st->adc_base_spear6xx->status);
0102 }
0103
0104 static void spear_adc_set_clk(struct spear_adc_state *st, u32 val)
0105 {
0106 u32 clk_high, clk_low, count;
0107 u32 apb_clk = clk_get_rate(st->clk);
0108
0109 count = DIV_ROUND_UP(apb_clk, val);
0110 clk_low = count / 2;
0111 clk_high = count - clk_low;
0112 st->current_clk = apb_clk / count;
0113
0114 __raw_writel(SPEAR_ADC_CLK_LOW(clk_low) | SPEAR_ADC_CLK_HIGH(clk_high),
0115 &st->adc_base_spear6xx->clk);
0116 }
0117
0118 static void spear_adc_set_ctrl(struct spear_adc_state *st, int n,
0119 u32 val)
0120 {
0121 __raw_writel(val, &st->adc_base_spear6xx->ch_ctrl[n]);
0122 }
0123
0124 static u32 spear_adc_get_average(struct spear_adc_state *st)
0125 {
0126 if (of_device_is_compatible(st->np, "st,spear600-adc")) {
0127 return __raw_readl(&st->adc_base_spear6xx->average.msb) &
0128 SPEAR_ADC_DATA_MASK;
0129 } else {
0130 return __raw_readl(&st->adc_base_spear3xx->average) &
0131 SPEAR_ADC_DATA_MASK;
0132 }
0133 }
0134
0135 static void spear_adc_set_scanrate(struct spear_adc_state *st, u32 rate)
0136 {
0137 if (of_device_is_compatible(st->np, "st,spear600-adc")) {
0138 __raw_writel(SPEAR600_ADC_SCAN_RATE_LO(rate),
0139 &st->adc_base_spear6xx->scan_rate_lo);
0140 __raw_writel(SPEAR600_ADC_SCAN_RATE_HI(rate),
0141 &st->adc_base_spear6xx->scan_rate_hi);
0142 } else {
0143 __raw_writel(rate, &st->adc_base_spear3xx->scan_rate);
0144 }
0145 }
0146
0147 static int spear_adc_read_raw(struct iio_dev *indio_dev,
0148 struct iio_chan_spec const *chan,
0149 int *val,
0150 int *val2,
0151 long mask)
0152 {
0153 struct spear_adc_state *st = iio_priv(indio_dev);
0154 u32 status;
0155
0156 switch (mask) {
0157 case IIO_CHAN_INFO_RAW:
0158 mutex_lock(&st->lock);
0159
0160 status = SPEAR_ADC_STATUS_CHANNEL_NUM(chan->channel) |
0161 SPEAR_ADC_STATUS_AVG_SAMPLE(st->avg_samples) |
0162 SPEAR_ADC_STATUS_START_CONVERSION |
0163 SPEAR_ADC_STATUS_ADC_ENABLE;
0164 if (st->vref_external == 0)
0165 status |= SPEAR_ADC_STATUS_VREF_INTERNAL;
0166
0167 spear_adc_set_status(st, status);
0168 wait_for_completion(&st->completion);
0169 *val = st->value;
0170
0171 mutex_unlock(&st->lock);
0172
0173 return IIO_VAL_INT;
0174
0175 case IIO_CHAN_INFO_SCALE:
0176 *val = st->vref_external;
0177 *val2 = SPEAR_ADC_DATA_BITS;
0178 return IIO_VAL_FRACTIONAL_LOG2;
0179 case IIO_CHAN_INFO_SAMP_FREQ:
0180 *val = st->current_clk;
0181 return IIO_VAL_INT;
0182 }
0183
0184 return -EINVAL;
0185 }
0186
0187 static int spear_adc_write_raw(struct iio_dev *indio_dev,
0188 struct iio_chan_spec const *chan,
0189 int val,
0190 int val2,
0191 long mask)
0192 {
0193 struct spear_adc_state *st = iio_priv(indio_dev);
0194 int ret = 0;
0195
0196 if (mask != IIO_CHAN_INFO_SAMP_FREQ)
0197 return -EINVAL;
0198
0199 mutex_lock(&st->lock);
0200
0201 if ((val < SPEAR_ADC_CLK_MIN) ||
0202 (val > SPEAR_ADC_CLK_MAX) ||
0203 (val2 != 0)) {
0204 ret = -EINVAL;
0205 goto out;
0206 }
0207
0208 spear_adc_set_clk(st, val);
0209
0210 out:
0211 mutex_unlock(&st->lock);
0212 return ret;
0213 }
0214
0215 #define SPEAR_ADC_CHAN(idx) { \
0216 .type = IIO_VOLTAGE, \
0217 .indexed = 1, \
0218 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
0219 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
0220 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),\
0221 .channel = idx, \
0222 }
0223
0224 static const struct iio_chan_spec spear_adc_iio_channels[] = {
0225 SPEAR_ADC_CHAN(0),
0226 SPEAR_ADC_CHAN(1),
0227 SPEAR_ADC_CHAN(2),
0228 SPEAR_ADC_CHAN(3),
0229 SPEAR_ADC_CHAN(4),
0230 SPEAR_ADC_CHAN(5),
0231 SPEAR_ADC_CHAN(6),
0232 SPEAR_ADC_CHAN(7),
0233 };
0234
0235 static irqreturn_t spear_adc_isr(int irq, void *dev_id)
0236 {
0237 struct spear_adc_state *st = dev_id;
0238
0239
0240 st->value = spear_adc_get_average(st);
0241 complete(&st->completion);
0242
0243 return IRQ_HANDLED;
0244 }
0245
0246 static int spear_adc_configure(struct spear_adc_state *st)
0247 {
0248 int i;
0249
0250
0251 spear_adc_set_status(st, 0);
0252 __raw_writel(0, &st->adc_base_spear6xx->clk);
0253 for (i = 0; i < 8; i++)
0254 spear_adc_set_ctrl(st, i, 0);
0255 spear_adc_set_scanrate(st, 0);
0256
0257 spear_adc_set_clk(st, st->sampling_freq);
0258
0259 return 0;
0260 }
0261
0262 static const struct iio_info spear_adc_info = {
0263 .read_raw = &spear_adc_read_raw,
0264 .write_raw = &spear_adc_write_raw,
0265 };
0266
0267 static int spear_adc_probe(struct platform_device *pdev)
0268 {
0269 struct device_node *np = pdev->dev.of_node;
0270 struct device *dev = &pdev->dev;
0271 struct spear_adc_state *st;
0272 struct iio_dev *indio_dev = NULL;
0273 int ret = -ENODEV;
0274 int irq;
0275
0276 indio_dev = devm_iio_device_alloc(dev, sizeof(struct spear_adc_state));
0277 if (!indio_dev) {
0278 dev_err(dev, "failed allocating iio device\n");
0279 return -ENOMEM;
0280 }
0281
0282 st = iio_priv(indio_dev);
0283
0284 mutex_init(&st->lock);
0285
0286 st->np = np;
0287
0288
0289
0290
0291
0292
0293 st->adc_base_spear6xx = devm_platform_ioremap_resource(pdev, 0);
0294 if (IS_ERR(st->adc_base_spear6xx))
0295 return PTR_ERR(st->adc_base_spear6xx);
0296
0297 st->adc_base_spear3xx =
0298 (struct adc_regs_spear3xx __iomem *)st->adc_base_spear6xx;
0299
0300 st->clk = devm_clk_get(dev, NULL);
0301 if (IS_ERR(st->clk)) {
0302 dev_err(dev, "failed getting clock\n");
0303 return PTR_ERR(st->clk);
0304 }
0305
0306 ret = clk_prepare_enable(st->clk);
0307 if (ret) {
0308 dev_err(dev, "failed enabling clock\n");
0309 return ret;
0310 }
0311
0312 irq = platform_get_irq(pdev, 0);
0313 if (irq <= 0) {
0314 ret = -EINVAL;
0315 goto errout2;
0316 }
0317
0318 ret = devm_request_irq(dev, irq, spear_adc_isr, 0, SPEAR_ADC_MOD_NAME,
0319 st);
0320 if (ret < 0) {
0321 dev_err(dev, "failed requesting interrupt\n");
0322 goto errout2;
0323 }
0324
0325 if (of_property_read_u32(np, "sampling-frequency",
0326 &st->sampling_freq)) {
0327 dev_err(dev, "sampling-frequency missing in DT\n");
0328 ret = -EINVAL;
0329 goto errout2;
0330 }
0331
0332
0333
0334
0335
0336 of_property_read_u32(np, "average-samples", &st->avg_samples);
0337
0338
0339
0340
0341
0342 of_property_read_u32(np, "vref-external", &st->vref_external);
0343
0344 spear_adc_configure(st);
0345
0346 platform_set_drvdata(pdev, indio_dev);
0347
0348 init_completion(&st->completion);
0349
0350 indio_dev->name = SPEAR_ADC_MOD_NAME;
0351 indio_dev->info = &spear_adc_info;
0352 indio_dev->modes = INDIO_DIRECT_MODE;
0353 indio_dev->channels = spear_adc_iio_channels;
0354 indio_dev->num_channels = ARRAY_SIZE(spear_adc_iio_channels);
0355
0356 ret = iio_device_register(indio_dev);
0357 if (ret)
0358 goto errout2;
0359
0360 dev_info(dev, "SPEAR ADC driver loaded, IRQ %d\n", irq);
0361
0362 return 0;
0363
0364 errout2:
0365 clk_disable_unprepare(st->clk);
0366 return ret;
0367 }
0368
0369 static int spear_adc_remove(struct platform_device *pdev)
0370 {
0371 struct iio_dev *indio_dev = platform_get_drvdata(pdev);
0372 struct spear_adc_state *st = iio_priv(indio_dev);
0373
0374 iio_device_unregister(indio_dev);
0375 clk_disable_unprepare(st->clk);
0376
0377 return 0;
0378 }
0379
0380 #ifdef CONFIG_OF
0381 static const struct of_device_id spear_adc_dt_ids[] = {
0382 { .compatible = "st,spear600-adc", },
0383 { }
0384 };
0385 MODULE_DEVICE_TABLE(of, spear_adc_dt_ids);
0386 #endif
0387
0388 static struct platform_driver spear_adc_driver = {
0389 .probe = spear_adc_probe,
0390 .remove = spear_adc_remove,
0391 .driver = {
0392 .name = SPEAR_ADC_MOD_NAME,
0393 .of_match_table = of_match_ptr(spear_adc_dt_ids),
0394 },
0395 };
0396
0397 module_platform_driver(spear_adc_driver);
0398
0399 MODULE_AUTHOR("Stefan Roese <sr@denx.de>");
0400 MODULE_DESCRIPTION("SPEAr ADC driver");
0401 MODULE_LICENSE("GPL");