static int tiadc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { struct tiadc_device *adc_dev = iio_priv(indio_dev); int i; unsigned int fifo1count, readx1; /* * When the sub-system is first enabled, * the sequencer will always start with the * lowest step (1) and continue until step (16). * For ex: If we have enabled 4 ADC channels and * currently use only 1 out of them, the * sequencer still configures all the 4 steps, * leading to 3 unwanted data. * Hence we need to flush out this data. */ fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT); for (i = 0; i < fifo1count; i++) { readx1 = tiadc_readl(adc_dev, REG_FIFO1); if (i == chan->channel) *val = readx1 & 0xfff; } tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB); return IIO_VAL_INT; }
static int tiadc_resume(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct tiadc_device *adc_dev = iio_priv(indio_dev); unsigned int restore; /* Make sure ADC is powered up */ restore = tiadc_readl(adc_dev, REG_CTRL); restore &= ~(CNTRLREG_POWERDOWN); tiadc_writel(adc_dev, REG_CTRL, restore); tiadc_step_config(adc_dev); return 0; }
static int tiadc_suspend(struct device *dev) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct tiadc_device *adc_dev = iio_priv(indio_dev); struct ti_tscadc_dev *tscadc_dev = dev->platform_data; unsigned int idle; if (!device_may_wakeup(tscadc_dev->dev)) { idle = tiadc_readl(adc_dev, REG_CTRL); idle &= ~(CNTRLREG_TSCSSENB); tiadc_writel(adc_dev, REG_CTRL, (idle | CNTRLREG_POWERDOWN)); } return 0; }
chan = adc_dev->channel_line[i]; tiadc_writel(adc_dev, REG_STEPCONFIG(steps), stepconfig | STEPCONFIG_INP(chan)); tiadc_writel(adc_dev, REG_STEPDELAY(steps), STEPCONFIG_OPENDLY); adc_dev->channel_step[i] = steps; steps++; } } static irqreturn_t tiadc_irq_h(int irq, void *private) { struct iio_dev *indio_dev = private; struct tiadc_device *adc_dev = iio_priv(indio_dev); unsigned int status, config; status = tiadc_readl(adc_dev, REG_IRQSTATUS); /* * ADC and touchscreen share the IRQ line. * FIFO0 interrupts are used by TSC. Handle FIFO1 IRQs here only */ if (status & IRQENB_FIFO1OVRRUN) { /* FIFO Overrun. Clear flag. Disable/Enable ADC to recover */ config = tiadc_readl(adc_dev, REG_CTRL); config &= ~(CNTRLREG_TSCSSENB); tiadc_writel(adc_dev, REG_CTRL, config); tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW | IRQENB_FIFO1THRES); tiadc_writel(adc_dev, REG_CTRL, (config | CNTRLREG_TSCSSENB)); return IRQ_HANDLED; } else if (status & IRQENB_FIFO1THRES) {