aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Thalmeier <michael.thalmeier@hale.at>2012-02-20 06:18:13 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2012-03-06 12:46:30 -0500
commit1039d762d03b573de4d46603c8583051c6d79094 (patch)
tree4de96496e62cb391cc824d7dbe328d0818f213d8
parent4d75dd61dfb53eaa286c54fb121e5b51b106c272 (diff)
mfd: Add pdata to set mc13783-ts conversion delay
MC13783 can be programmed to wait some clock cycles between the touchscreen polarization and the resistance conversion. This is needed to adjust for touchscreens with high capacitance between plates. Signed-off-by: Michael Thalmeier <michael.thalmeier@hale.at> Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Acked-by: Dmitry Torokhov <dtor@mail.ru> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--drivers/hwmon/mc13783-adc.c2
-rw-r--r--drivers/input/touchscreen/mc13783_ts.c11
-rw-r--r--drivers/mfd/mc13xxx-core.c11
-rw-r--r--include/linux/mfd/mc13xxx.h16
4 files changed, 35 insertions, 5 deletions
diff --git a/drivers/hwmon/mc13783-adc.c b/drivers/hwmon/mc13783-adc.c
index ef65ab56b094..6acd04427723 100644
--- a/drivers/hwmon/mc13783-adc.c
+++ b/drivers/hwmon/mc13783-adc.c
@@ -53,7 +53,7 @@ static int mc13783_adc_read(struct device *dev,
53 53
54 ret = mc13xxx_adc_do_conversion(priv->mc13xxx, 54 ret = mc13xxx_adc_do_conversion(priv->mc13xxx,
55 MC13XXX_ADC_MODE_MULT_CHAN, 55 MC13XXX_ADC_MODE_MULT_CHAN,
56 channel, sample); 56 channel, 0, 0, sample);
57 if (ret) 57 if (ret)
58 return ret; 58 return ret;
59 59
diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c
index ede02743eac1..48dc5b0d26f1 100644
--- a/drivers/input/touchscreen/mc13783_ts.c
+++ b/drivers/input/touchscreen/mc13783_ts.c
@@ -39,6 +39,7 @@ struct mc13783_ts_priv {
39 struct delayed_work work; 39 struct delayed_work work;
40 struct workqueue_struct *workq; 40 struct workqueue_struct *workq;
41 unsigned int sample[4]; 41 unsigned int sample[4];
42 struct mc13xxx_ts_platform_data *touch;
42}; 43};
43 44
44static irqreturn_t mc13783_ts_handler(int irq, void *data) 45static irqreturn_t mc13783_ts_handler(int irq, void *data)
@@ -125,7 +126,9 @@ static void mc13783_ts_work(struct work_struct *work)
125 unsigned int channel = 12; 126 unsigned int channel = 12;
126 127
127 if (mc13xxx_adc_do_conversion(priv->mc13xxx, 128 if (mc13xxx_adc_do_conversion(priv->mc13xxx,
128 mode, channel, priv->sample) == 0) 129 mode, channel,
130 priv->touch->ato, priv->touch->atox,
131 priv->sample) == 0)
129 mc13783_ts_report_sample(priv); 132 mc13783_ts_report_sample(priv);
130} 133}
131 134
@@ -179,6 +182,12 @@ static int __init mc13783_ts_probe(struct platform_device *pdev)
179 INIT_DELAYED_WORK(&priv->work, mc13783_ts_work); 182 INIT_DELAYED_WORK(&priv->work, mc13783_ts_work);
180 priv->mc13xxx = dev_get_drvdata(pdev->dev.parent); 183 priv->mc13xxx = dev_get_drvdata(pdev->dev.parent);
181 priv->idev = idev; 184 priv->idev = idev;
185 priv->touch = dev_get_platdata(&pdev->dev);
186 if (!priv->touch) {
187 dev_err(&pdev->dev, "missing platform data\n");
188 ret = -ENODEV;
189 goto err_free_mem;
190 }
182 191
183 /* 192 /*
184 * We need separate workqueue because mc13783_adc_do_conversion 193 * We need separate workqueue because mc13783_adc_do_conversion
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index 7122386b4e3c..9fd4f63c45cc 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -560,6 +560,8 @@ EXPORT_SYMBOL(mc13xxx_get_flags);
560 560
561#define MC13XXX_ADC1_CHAN0_SHIFT 5 561#define MC13XXX_ADC1_CHAN0_SHIFT 5
562#define MC13XXX_ADC1_CHAN1_SHIFT 8 562#define MC13XXX_ADC1_CHAN1_SHIFT 8
563#define MC13783_ADC1_ATO_SHIFT 11
564#define MC13783_ADC1_ATOX (1 << 19)
563 565
564struct mc13xxx_adcdone_data { 566struct mc13xxx_adcdone_data {
565 struct mc13xxx *mc13xxx; 567 struct mc13xxx *mc13xxx;
@@ -580,7 +582,8 @@ static irqreturn_t mc13xxx_handler_adcdone(int irq, void *data)
580#define MC13XXX_ADC_WORKING (1 << 0) 582#define MC13XXX_ADC_WORKING (1 << 0)
581 583
582int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, 584int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
583 unsigned int channel, unsigned int *sample) 585 unsigned int channel, u8 ato, bool atox,
586 unsigned int *sample)
584{ 587{
585 u32 adc0, adc1, old_adc0; 588 u32 adc0, adc1, old_adc0;
586 int i, ret; 589 int i, ret;
@@ -631,6 +634,9 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
631 return -EINVAL; 634 return -EINVAL;
632 } 635 }
633 636
637 adc1 |= ato << MC13783_ADC1_ATO_SHIFT;
638 if (atox)
639 adc1 |= MC13783_ADC1_ATOX;
634 dev_dbg(&mc13xxx->spidev->dev, "%s: request irq\n", __func__); 640 dev_dbg(&mc13xxx->spidev->dev, "%s: request irq\n", __func__);
635 mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, 641 mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE,
636 mc13xxx_handler_adcdone, __func__, &adcdone_data); 642 mc13xxx_handler_adcdone, __func__, &adcdone_data);
@@ -813,7 +819,8 @@ err_revision:
813 mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); 819 mc13xxx_add_subdevice(mc13xxx, "%s-rtc");
814 820
815 if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN) 821 if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN)
816 mc13xxx_add_subdevice(mc13xxx, "%s-ts"); 822 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-ts",
823 &pdata->touch, sizeof(pdata->touch));
817 824
818 if (pdata) { 825 if (pdata) {
819 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", 826 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
diff --git a/include/linux/mfd/mc13xxx.h b/include/linux/mfd/mc13xxx.h
index b86ee45c8b03..10e038bac8dd 100644
--- a/include/linux/mfd/mc13xxx.h
+++ b/include/linux/mfd/mc13xxx.h
@@ -38,7 +38,8 @@ int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq);
38int mc13xxx_get_flags(struct mc13xxx *mc13xxx); 38int mc13xxx_get_flags(struct mc13xxx *mc13xxx);
39 39
40int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, 40int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx,
41 unsigned int mode, unsigned int channel, unsigned int *sample); 41 unsigned int mode, unsigned int channel,
42 u8 ato, bool atox, unsigned int *sample);
42 43
43#define MC13XXX_IRQ_ADCDONE 0 44#define MC13XXX_IRQ_ADCDONE 0
44#define MC13XXX_IRQ_ADCBISDONE 1 45#define MC13XXX_IRQ_ADCBISDONE 1
@@ -157,6 +158,18 @@ struct mc13xxx_buttons_platform_data {
157 unsigned short b3on_key; 158 unsigned short b3on_key;
158}; 159};
159 160
161struct mc13xxx_ts_platform_data {
162 /* Delay between Touchscreen polarization and ADC Conversion.
163 * Given in clock ticks of a 32 kHz clock which gives a granularity of
164 * about 30.5ms */
165 u8 ato;
166
167#define MC13783_TS_ATO_FIRST false
168#define MC13783_TS_ATO_EACH true
169 /* Use the ATO delay only for the first conversion or for each one */
170 bool atox;
171};
172
160struct mc13xxx_platform_data { 173struct mc13xxx_platform_data {
161#define MC13XXX_USE_TOUCHSCREEN (1 << 0) 174#define MC13XXX_USE_TOUCHSCREEN (1 << 0)
162#define MC13XXX_USE_CODEC (1 << 1) 175#define MC13XXX_USE_CODEC (1 << 1)
@@ -167,6 +180,7 @@ struct mc13xxx_platform_data {
167 struct mc13xxx_regulator_platform_data regulators; 180 struct mc13xxx_regulator_platform_data regulators;
168 struct mc13xxx_leds_platform_data *leds; 181 struct mc13xxx_leds_platform_data *leds;
169 struct mc13xxx_buttons_platform_data *buttons; 182 struct mc13xxx_buttons_platform_data *buttons;
183 struct mc13xxx_ts_platform_data touch;
170}; 184};
171 185
172#define MC13XXX_ADC_MODE_TS 1 186#define MC13XXX_ADC_MODE_TS 1