Hi Jonathan, On 25 August 2018 at 16:38, Jonathan Cameron <jic23@xxxxxxxxxx> wrote: > On Fri, 24 Aug 2018 17:53:15 +0800 > Baolin Wang <baolin.wang@xxxxxxxxxx> wrote: > >> The headset device will use channel 20 of ADC controller to detect events, >> but it needs the raw ADC data to do conversion according to its own formula. >> >> Thus we should configure the channel mask separately and configure channel >> 20 as IIO_CHAN_INFO_RAW, as well as adding raw data read support. > > So is this a general thing, i.e. that channel is 'meant' to be used for the > headset, or just a one off for a particular board? > If it is a general thing, than I'm fine with this (unlikely we'll break any > other users), but if not we need to find a nicer way to do it. Yes, it is a general thing. Now channel 20 is always used for the headset. > I am a little unclear on how a channel would provide the voltage on it's pin > but that could be wrong when used for a different purpose? > If it's just a matter of unusual loading characteristics then perhaps that > is valid, but I'd like to understand this a little. On our platform, the headset will use this voltage value reading from ADC to check the headset events: headset buttons, headset plugin and so on. >> >> Signed-off-by: Baolin Wang <baolin.wang@xxxxxxxxxx> >> --- >> drivers/iio/adc/sc27xx_adc.c | 80 ++++++++++++++++++++++++------------------ >> 1 file changed, 45 insertions(+), 35 deletions(-) >> >> diff --git a/drivers/iio/adc/sc27xx_adc.c b/drivers/iio/adc/sc27xx_adc.c >> index 2b60efe..153c311 100644 >> --- a/drivers/iio/adc/sc27xx_adc.c >> +++ b/drivers/iio/adc/sc27xx_adc.c >> @@ -273,6 +273,17 @@ static int sc27xx_adc_read_raw(struct iio_dev *indio_dev, >> int ret, tmp; >> >> switch (mask) { >> + case IIO_CHAN_INFO_RAW: >> + mutex_lock(&indio_dev->mlock); >> + ret = sc27xx_adc_read(data, chan->channel, scale, &tmp); >> + mutex_unlock(&indio_dev->mlock); >> + >> + if (ret) >> + return ret; >> + >> + *val = tmp; >> + return IIO_VAL_INT; >> + >> case IIO_CHAN_INFO_PROCESSED: >> mutex_lock(&indio_dev->mlock); >> ret = sc27xx_adc_read_processed(data, chan->channel, scale, >> @@ -315,48 +326,47 @@ static int sc27xx_adc_write_raw(struct iio_dev *indio_dev, >> .write_raw = &sc27xx_adc_write_raw, >> }; >> >> -#define SC27XX_ADC_CHANNEL(index) { \ >> +#define SC27XX_ADC_CHANNEL(index, mask) { \ >> .type = IIO_VOLTAGE, \ >> .channel = index, \ >> - .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) | \ >> - BIT(IIO_CHAN_INFO_SCALE), \ >> + .info_mask_separate = mask | BIT(IIO_CHAN_INFO_SCALE), \ >> .datasheet_name = "CH##index", \ >> .indexed = 1, \ >> } >> >> static const struct iio_chan_spec sc27xx_channels[] = { >> - SC27XX_ADC_CHANNEL(0), >> - SC27XX_ADC_CHANNEL(1), >> - SC27XX_ADC_CHANNEL(2), >> - SC27XX_ADC_CHANNEL(3), >> - SC27XX_ADC_CHANNEL(4), >> - SC27XX_ADC_CHANNEL(5), >> - SC27XX_ADC_CHANNEL(6), >> - SC27XX_ADC_CHANNEL(7), >> - SC27XX_ADC_CHANNEL(8), >> - SC27XX_ADC_CHANNEL(9), >> - SC27XX_ADC_CHANNEL(10), >> - SC27XX_ADC_CHANNEL(11), >> - SC27XX_ADC_CHANNEL(12), >> - SC27XX_ADC_CHANNEL(13), >> - SC27XX_ADC_CHANNEL(14), >> - SC27XX_ADC_CHANNEL(15), >> - SC27XX_ADC_CHANNEL(16), >> - SC27XX_ADC_CHANNEL(17), >> - SC27XX_ADC_CHANNEL(18), >> - SC27XX_ADC_CHANNEL(19), >> - SC27XX_ADC_CHANNEL(20), >> - SC27XX_ADC_CHANNEL(21), >> - SC27XX_ADC_CHANNEL(22), >> - SC27XX_ADC_CHANNEL(23), >> - SC27XX_ADC_CHANNEL(24), >> - SC27XX_ADC_CHANNEL(25), >> - SC27XX_ADC_CHANNEL(26), >> - SC27XX_ADC_CHANNEL(27), >> - SC27XX_ADC_CHANNEL(28), >> - SC27XX_ADC_CHANNEL(29), >> - SC27XX_ADC_CHANNEL(30), >> - SC27XX_ADC_CHANNEL(31), >> + SC27XX_ADC_CHANNEL(0, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(1, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(2, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(3, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(4, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(5, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(6, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(7, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(8, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(9, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(10, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(11, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(12, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(13, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(14, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(15, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(16, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(17, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(18, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(19, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(20, BIT(IIO_CHAN_INFO_RAW)), >> + SC27XX_ADC_CHANNEL(21, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(22, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(23, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(24, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(25, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(26, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(27, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(28, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(29, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(30, BIT(IIO_CHAN_INFO_PROCESSED)), >> + SC27XX_ADC_CHANNEL(31, BIT(IIO_CHAN_INFO_PROCESSED)), >> }; >> >> static int sc27xx_adc_enable(struct sc27xx_adc_data *data) > -- Baolin Wang Best Regards