aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorOleksandr Dmytryshyn <oleksandr.dmytryshyn@ti.com>2012-03-02 13:08:10 +0200
committerZiyann <jaraidaniel@gmail.com>2014-10-01 13:00:33 +0200
commite19611621635522ff71c55adb401c090d5f8262f (patch)
treef4baa628a79cae24ca35a19ebaeaaf27ba6704cf /drivers/mfd
parent915830265b9e00f88585aa00f8af4b70a984fc66 (diff)
downloadkernel_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.c123
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");