diff options
author | Oleksandr Dmytryshyn <oleksandr.dmytryshyn@ti.com> | 2012-03-02 13:08:10 +0200 |
---|---|---|
committer | Ziyann <jaraidaniel@gmail.com> | 2014-10-01 13:00:33 +0200 |
commit | e19611621635522ff71c55adb401c090d5f8262f (patch) | |
tree | f4baa628a79cae24ca35a19ebaeaaf27ba6704cf /drivers/mfd | |
parent | 915830265b9e00f88585aa00f8af4b70a984fc66 (diff) | |
download | kernel_samsung_tuna-e19611621635522ff71c55adb401c090d5f8262f.zip kernel_samsung_tuna-e19611621635522ff71c55adb401c090d5f8262f.tar.gz kernel_samsung_tuna-e19611621635522ff71c55adb401c090d5f8262f.tar.bz2 |
MFD: TWL6030: Remove the TWL6032_GPADC_SW2 conversion method
Lets gpacd module will be detect the twl6030 or twl6032 chip and
use appropriate software conversion method.
Change-Id: I2eac6e0b9e97b37e13cfa2bfbc9a0956fc68d1a9
Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@ti.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/twl6030-gpadc.c | 123 |
1 files changed, 80 insertions, 43 deletions
diff --git a/drivers/mfd/twl6030-gpadc.c b/drivers/mfd/twl6030-gpadc.c index 948116e..de204f8 100644 --- a/drivers/mfd/twl6030-gpadc.c +++ b/drivers/mfd/twl6030-gpadc.c @@ -48,7 +48,6 @@ #define GPADCS (1 << 1) #define GPADCR (1 << 0) -#define TWL6030_GPADC_MASK 0x20 #define SCALE (1 << 15) struct twl6030_chnl_calib { @@ -307,11 +306,12 @@ struct twl6030_gpadc_data { static struct twl6030_gpadc_data *the_gpadc; -static -const struct twl6030_gpadc_conversion_method twl6030_conversion_methods[] = { +static const +struct twl6030_gpadc_conversion_method twl6030_conversion_methods_table[] = { [TWL6030_GPADC_RT] = { .sel = TWL6030_GPADC_RTSELECT_LSB, .rbase = TWL6030_GPADC_RTCH0_LSB, + .mask = TWL6030_GPADC_RT_SW1_EOC_MASK, }, /* * TWL6030_GPADC_SW1 is not supported as @@ -321,15 +321,29 @@ const struct twl6030_gpadc_conversion_method twl6030_conversion_methods[] = { .rbase = TWL6030_GPADC_GPCH0_LSB, .ctrl = TWL6030_GPADC_CTRL_P2, .enable = TWL6030_GPADC_CTRL_P2_SP2, + .mask = TWL6030_GPADC_SW2_EOC_MASK, }, - [TWL6032_GPADC_SW2] = { +}; + +static const +struct twl6030_gpadc_conversion_method twl6032_conversion_methods_table[] = { + [TWL6030_GPADC_RT] = { + .sel = TWL6032_GPADC_RTSELECT_LSB, + .rbase = TWL6032_RTCH0_LSB, + .mask = TWL6032_GPADC_RT_EOC_MASK, + }, + [TWL6030_GPADC_SW2] = { .sel = TWL6032_GPADC_GPSELECT_ISB, - .rbase = TWL6030_GPADC_GPCH0_LSB, + .rbase = TWL6032_GPCH0_LSB, .ctrl = TWL6032_GPADC_CTRL_P1, .enable = TWL6030_GPADC_CTRL_P1_SP1, + .mask = TWL6032_GPADC_SW_EOC_MASK, }, }; +static const +struct twl6030_gpadc_conversion_method *twl6030_conversion_methods; + static ssize_t show_gain(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -417,19 +431,12 @@ static int twl6030_gpadc_channel_raw_read(struct twl6030_gpadc_data *gpadc, { u8 msb, lsb; - if (gpadc->features & TWL6032_SUBCLASS) { - /* read the channel data */ - msb = twl6030_gpadc_read(gpadc, TWL6032_GPCH0_MSB); - lsb = twl6030_gpadc_read(gpadc, TWL6032_GPCH0_LSB); - } else { - - /* For each ADC channel, we have MSB and LSB register pair. - * MSB address is always LSB address+1. reg parameter is the - * addr of LSB register - */ - msb = twl6030_gpadc_read(gpadc, reg + 1); - lsb = twl6030_gpadc_read(gpadc, reg); - } + /* For each ADC channel, we have MSB and LSB register pair. + * MSB address is always LSB address+1. reg parameter is the + * addr of LSB register + */ + msb = twl6030_gpadc_read(gpadc, reg + 1); + lsb = twl6030_gpadc_read(gpadc, reg); return (int)((msb << 8) | lsb); } @@ -449,8 +456,11 @@ static int twl6030_gpadc_read_channels(struct twl6030_gpadc_data *gpadc, for (i = 0; i < TWL6032_GPADC_MAX_CHANNELS; i++) { if (channels & BIT(i)) continue; + + reg = reg_base + 2 * count; + dev_dbg(gpadc->dev, "GPADC chn: %d\n", i); - raw_code = twl6030_gpadc_channel_raw_read(gpadc, 0); + raw_code = twl6030_gpadc_channel_raw_read(gpadc, reg); dev_dbg(gpadc->dev, "GPADC raw: %d\n", raw_code); count++; req->buf[i].raw_code = raw_code; @@ -521,23 +531,17 @@ static int twl6030_gpadc_read_channels(struct twl6030_gpadc_data *gpadc, static void twl6030_gpadc_enable_irq(u16 method) { - if (method == TWL6032_GPADC_SW2) - method = TWL6030_GPADC_SW2; - - twl6030_interrupt_unmask(TWL6030_GPADC_MASK << method, + twl6030_interrupt_unmask(twl6030_conversion_methods[method].mask, REG_INT_MSK_LINE_B); - twl6030_interrupt_unmask(TWL6030_GPADC_MASK << method, + twl6030_interrupt_unmask(twl6030_conversion_methods[method].mask, REG_INT_MSK_STS_B); } static void twl6030_gpadc_disable_irq(u16 method) { - if (method == TWL6032_GPADC_SW2) - method = TWL6030_GPADC_SW2; - - twl6030_interrupt_mask(TWL6030_GPADC_MASK << method, + twl6030_interrupt_mask(twl6030_conversion_methods[method].mask, REG_INT_MSK_LINE_B); - twl6030_interrupt_mask(TWL6030_GPADC_MASK << method, + twl6030_interrupt_mask(twl6030_conversion_methods[method].mask, REG_INT_MSK_STS_B); } @@ -628,7 +632,6 @@ twl6030_gpadc_start_conversion(struct twl6030_gpadc_data *gpadc, switch (conv_method) { case TWL6030_GPADC_SW2: - case TWL6032_GPADC_SW2: twl6030_gpadc_write(gpadc, method->ctrl, method->enable); break; case TWL6030_GPADC_RT: @@ -716,7 +719,45 @@ out: static int _twl6032_gpadc_conversion(struct twl6030_gpadc_request *req, const struct twl6030_gpadc_conversion_method *method) { - int i, ret, count = 0; + int i, ret, count = 0, channelcnt = 0; + u8 ch_msb, ch_lsb, ch_isb; + + if ((req->type == TWL6030_GPADC_IRQ_ONESHOT) && + (req->func_cb == NULL)) { + ret = -EINVAL; + goto out; + } + + for (i = 0; i < TWL6032_GPADC_MAX_CHANNELS; i++) + if (req->channels & BIT(i)) + channelcnt++; + + if (req->method == TWL6030_GPADC_RT) { + /* + * For the TWL6032 real time conversion + * maximum channels count is 2 + */ + if ((req->type != TWL6030_GPADC_IRQ_ONESHOT) || + (channelcnt > 2)) { + ret = -EINVAL; + goto out; + } + + ch_msb = (req->channels >> 16) & 0x07; + ch_isb = (req->channels >> 8) & 0xff; + ch_lsb = req->channels & 0xff; + twl6030_gpadc_write(the_gpadc, method->sel + 2, ch_msb); + twl6030_gpadc_write(the_gpadc, method->sel + 1, ch_isb); + twl6030_gpadc_write(the_gpadc, method->sel, ch_lsb); + } + + if (req->type == TWL6030_GPADC_IRQ_ONESHOT) { + twl6030_gpadc_set_irq(the_gpadc, req); + twl6030_gpadc_start_conversion(the_gpadc, req->method); + the_gpadc->requests[req->method].active = 1; + ret = 0; + goto out; + } for (i = 0; i < TWL6032_GPADC_MAX_CHANNELS; i++) { if (!(req->channels & BIT(i))) @@ -799,10 +840,7 @@ static ssize_t show_channel(struct device *dev, int ret; req.channels = (1 << attr->index); - if (the_gpadc->features & TWL6032_SUBCLASS) - req.method = TWL6032_GPADC_SW2; - else - req.method = TWL6030_GPADC_SW2; + req.method = TWL6030_GPADC_SW2; req.active = 0; req.func_cb = NULL; ret = twl6030_gpadc_conversion(&req); @@ -826,10 +864,7 @@ static ssize_t show_raw_code(struct device *dev, int ret; req.channels = (1 << attr->index); - if (the_gpadc->features & TWL6032_SUBCLASS) - req.method = TWL6032_GPADC_SW2; - else - req.method = TWL6030_GPADC_SW2; + req.method = TWL6030_GPADC_SW2; req.active = 0; req.func_cb = NULL; ret = twl6030_gpadc_conversion(&req); @@ -971,10 +1006,7 @@ static long twl6030_gpadc_ioctl(struct file *filp, unsigned int cmd, } req.channels = (1 << par.channel); - if (the_gpadc->features & TWL6032_SUBCLASS) - req.method = TWL6032_GPADC_SW2; - else - req.method = TWL6030_GPADC_SW2; + req.method = TWL6030_GPADC_SW2; req.func_cb = NULL; req.type = TWL6030_GPADC_WAIT; @@ -1262,6 +1294,11 @@ static int __devinit twl6030_gpadc_probe(struct platform_device *pdev) gpadc->features = pdata->features; + twl6030_conversion_methods = twl6030_conversion_methods_table; + + if (gpadc->features & TWL6032_SUBCLASS) + twl6030_conversion_methods = twl6032_conversion_methods_table; + ret = misc_register(&twl6030_gpadc_device); if (ret) { dev_dbg(&pdev->dev, "could not register misc_device\n"); |