aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorRobin Gong <b38343@freescale.com>2013-08-13 04:58:26 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:01:17 -0400
commit678199152705826f1fee736759d53e56155508bd (patch)
tree84c309de2559971eb19bb6f72d99d99ed09dc6fc /drivers/input
parent15234a889258cb544f74c06a6f2db052f560a6e4 (diff)
ENGR00275004-1 input: touchscreen: max11801_ts: Add DCM mode for max11801 ADC
We need add DCM mode/AUX mode for ADC converter function of max11801, so that it can be used to read voltage of battery. Meanwhile, let the driver based on device tree. The patchset is based on below patch (V3.5.7): commit 4001774cf51f0140ae7e4e8e0ec1d86475790682 Author: Rong Dian <b38775@freescale.com> Date: Fri Jan 18 14:24:28 2013 +0800 Engr00240284-1 MAX11801: Add DCM aux adc sample function 1.Add direct conversion mode operations 2.Add aux adc sample function Signed-off-by: Robin Gong <b38343@freescale.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/max11801_ts.c195
1 files changed, 168 insertions, 27 deletions
diff --git a/drivers/input/touchscreen/max11801_ts.c b/drivers/input/touchscreen/max11801_ts.c
index 00bc6caa27f5..051d38f0339f 100644
--- a/drivers/input/touchscreen/max11801_ts.c
+++ b/drivers/input/touchscreen/max11801_ts.c
@@ -2,7 +2,7 @@
2 * Driver for MAXI MAX11801 - A Resistive touch screen controller with 2 * Driver for MAXI MAX11801 - A Resistive touch screen controller with
3 * i2c interface 3 * i2c interface
4 * 4 *
5 * Copyright (C) 2011 Freescale Semiconductor, Inc. 5 * Copyright (C) 2011-2013 Freescale Semiconductor, Inc.
6 * Author: Zhang Jiejing <jiejing.zhang@freescale.com> 6 * Author: Zhang Jiejing <jiejing.zhang@freescale.com>
7 * 7 *
8 * Based on mcs5000_ts.c 8 * Based on mcs5000_ts.c
@@ -39,6 +39,10 @@
39#include <linux/input.h> 39#include <linux/input.h>
40#include <linux/slab.h> 40#include <linux/slab.h>
41#include <linux/bitops.h> 41#include <linux/bitops.h>
42#include <linux/delay.h>
43#include <linux/io.h>
44#include <linux/of.h>
45#include <linux/of_device.h>
42 46
43/* Register Address define */ 47/* Register Address define */
44#define GENERNAL_STATUS_REG 0x00 48#define GENERNAL_STATUS_REG 0x00
@@ -54,13 +58,30 @@
54#define AUX_MESURE_CONF_REG 0x0a 58#define AUX_MESURE_CONF_REG 0x0a
55#define OP_MODE_CONF_REG 0x0b 59#define OP_MODE_CONF_REG 0x0b
56 60
61#define Panel_Setup_X (0x69 << 1)
62#define Panel_Setup_Y (0x6b << 1)
63
64#define XY_combined_measurement (0x70 << 1)
65#define X_measurement (0x78 << 1)
66#define Y_measurement (0x7a << 1)
67#define AUX_measurement (0x76 << 1)
68
57/* FIFO is found only in max11800 and max11801 */ 69/* FIFO is found only in max11800 and max11801 */
58#define FIFO_RD_CMD (0x50 << 1) 70#define FIFO_RD_CMD (0x50 << 1)
59#define MAX11801_FIFO_INT (1 << 2) 71#define MAX11801_FIFO_INT (1 << 2)
60#define MAX11801_FIFO_OVERFLOW (1 << 3) 72#define MAX11801_FIFO_OVERFLOW (1 << 3)
73#define MAX11801_EDGE_INT (1 << 1)
74
75#define FIFO_RD_X_MSB (0x52 << 1)
76#define FIFO_RD_X_LSB (0x53 << 1)
77#define FIFO_RD_Y_MSB (0x54 << 1)
78#define FIFO_RD_Y_LSB (0x55 << 1)
79#define FIFO_RD_AUX_MSB (0x5a << 1)
80#define FIFO_RD_AUX_LSB (0x5b << 1)
61 81
62#define XY_BUFSIZE 4 82#define XY_BUFSIZE 4
63#define XY_BUF_OFFSET 4 83#define XY_BUF_OFFSET 4
84#define AUX_BUFSIZE 2
64 85
65#define MAX11801_MAX_X 0xfff 86#define MAX11801_MAX_X 0xfff
66#define MAX11801_MAX_Y 0xfff 87#define MAX11801_MAX_Y 0xfff
@@ -85,6 +106,64 @@ struct max11801_data {
85 struct input_dev *input_dev; 106 struct input_dev *input_dev;
86}; 107};
87 108
109static struct i2c_client *max11801_client;
110static unsigned int max11801_workmode;
111static u8 aux_buf[AUX_BUFSIZE];
112
113static int max11801_dcm_write_command(struct i2c_client *client, int command)
114{
115 return i2c_smbus_write_byte(client, command);
116}
117
118static u32 max11801_dcm_sample_aux(struct i2c_client *client)
119{
120 int ret;
121 int aux = 0;
122 u32 sample_data;
123
124 /* AUX_measurement */
125 max11801_dcm_write_command(client, AUX_measurement);
126 mdelay(5);
127 ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_AUX_MSB,
128 1, &aux_buf[0]);
129 if (ret < 1) {
130 dev_err(&client->dev, "FIFO_RD_AUX_MSB read fails\n");
131 return ret;
132 }
133 mdelay(5);
134 ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_AUX_LSB,
135 1, &aux_buf[1]);
136 if (ret < 1) {
137 dev_err(&client->dev, "FIFO_RD_AUX_LSB read fails\n");
138 return ret;
139 }
140
141 aux = (aux_buf[0] << 4) + (aux_buf[1] >> 4);
142 /*
143 * voltage = (9170*aux)/7371;
144 * voltage is (26.2*3150*aux)/(16.2*0xFFF)
145 * V(aux)=3150*sample/0xFFF,V(battery)=212*V(aux)/81
146 * sample_data = (14840*aux)/7371-1541;
147 */
148 sample_data = (14840 * aux) / 7371;
149
150 return sample_data;
151}
152
153u32 max11801_read_adc(void)
154{
155 u32 adc_data;
156
157 if (!max11801_client) {
158 pr_err("FAIL max11801_client not initialize\n");
159 return -1;
160 }
161 adc_data = max11801_dcm_sample_aux(max11801_client);
162
163 return adc_data;
164}
165EXPORT_SYMBOL_GPL(max11801_read_adc);
166
88static u8 read_register(struct i2c_client *client, int addr) 167static u8 read_register(struct i2c_client *client, int addr)
89{ 168{
90 /* XXX: The chip ignores LSB of register address */ 169 /* XXX: The chip ignores LSB of register address */
@@ -105,29 +184,62 @@ static irqreturn_t max11801_ts_interrupt(int irq, void *dev_id)
105 u8 buf[XY_BUFSIZE]; 184 u8 buf[XY_BUFSIZE];
106 int x = -1; 185 int x = -1;
107 int y = -1; 186 int y = -1;
187 u8 command = FIFO_RD_X_MSB;
108 188
109 status = read_register(data->client, GENERNAL_STATUS_REG); 189 status = read_register(data->client, GENERNAL_STATUS_REG);
110 190 if ((!max11801_workmode && (status & (MAX11801_FIFO_INT |
111 if (status & (MAX11801_FIFO_INT | MAX11801_FIFO_OVERFLOW)) { 191 MAX11801_FIFO_OVERFLOW))) || (max11801_workmode && (status &
192 MAX11801_EDGE_INT))) {
112 status = read_register(data->client, GENERNAL_STATUS_REG); 193 status = read_register(data->client, GENERNAL_STATUS_REG);
113 194 if (!max11801_workmode) {
114 ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_CMD, 195 /* ACM mode */
115 XY_BUFSIZE, buf); 196 ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_CMD,
116 197 XY_BUFSIZE, buf);
117 /* 198 /*
118 * We should get 4 bytes buffer that contains X,Y 199 * We should get 4 bytes buffer that contains X,Y
119 * and event tag 200 * and event tag
120 */ 201 */
121 if (ret < XY_BUFSIZE) 202 if (ret < XY_BUFSIZE)
122 goto out; 203 goto out;
204 } else {
205 /* DCM mode */
206 /* X = panel setup */
207 max11801_dcm_write_command(client, Panel_Setup_X);
208 /* X_measurement */
209 max11801_dcm_write_command(client, X_measurement);
210 for (i = 0; i < 2; i++) {
211 ret = i2c_smbus_read_i2c_block_data(client,
212 command, 1, &buf[i]);
213 if (ret < 1)
214 goto out;
215
216 command = FIFO_RD_X_LSB;
217 }
218
219 /* Y = panel setup */
220 max11801_dcm_write_command(client, Panel_Setup_Y);
221 /* Y_measurement */
222 max11801_dcm_write_command(client, Y_measurement);
223 command = FIFO_RD_Y_MSB;
224 for (i = 2; i < XY_BUFSIZE; i++) {
225 ret = i2c_smbus_read_i2c_block_data(client,
226 command, 1, &buf[i]);
227 if (ret < 1)
228 goto out;
229
230 command = FIFO_RD_Y_LSB;
231 }
232 }
123 233
124 for (i = 0; i < XY_BUFSIZE; i += XY_BUFSIZE / 2) { 234 for (i = 0; i < XY_BUFSIZE; i += XY_BUFSIZE / 2) {
125 if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_X_TAG) 235 if ((buf[i + 1] & MEASURE_TAG_MASK) ==
236 MEASURE_X_TAG)
126 x = (buf[i] << XY_BUF_OFFSET) + 237 x = (buf[i] << XY_BUF_OFFSET) +
127 (buf[i + 1] >> XY_BUF_OFFSET); 238 (buf[i + 1] >> XY_BUF_OFFSET);
128 else if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_Y_TAG) 239 else if ((buf[i + 1] & MEASURE_TAG_MASK) ==
240 MEASURE_Y_TAG)
129 y = (buf[i] << XY_BUF_OFFSET) + 241 y = (buf[i] << XY_BUF_OFFSET) +
130 (buf[i + 1] >> XY_BUF_OFFSET); 242 (buf[i + 1] >> XY_BUF_OFFSET);
131 } 243 }
132 244
133 if ((buf[1] & EVENT_TAG_MASK) != (buf[3] & EVENT_TAG_MASK)) 245 if ((buf[1] & EVENT_TAG_MASK) != (buf[3] & EVENT_TAG_MASK))
@@ -138,18 +250,17 @@ static irqreturn_t max11801_ts_interrupt(int irq, void *dev_id)
138 /* fall through */ 250 /* fall through */
139 case EVENT_MIDDLE: 251 case EVENT_MIDDLE:
140 input_report_abs(data->input_dev, ABS_X, x); 252 input_report_abs(data->input_dev, ABS_X, x);
253 y = MAX11801_MAX_Y - y; /* Calibration */
141 input_report_abs(data->input_dev, ABS_Y, y); 254 input_report_abs(data->input_dev, ABS_Y, y);
142 input_event(data->input_dev, EV_KEY, BTN_TOUCH, 1); 255 input_event(data->input_dev, EV_KEY, BTN_TOUCH, 1);
143 input_sync(data->input_dev); 256 input_sync(data->input_dev);
144 break; 257 break;
145
146 case EVENT_RELEASE: 258 case EVENT_RELEASE:
147 input_event(data->input_dev, EV_KEY, BTN_TOUCH, 0); 259 input_event(data->input_dev, EV_KEY, BTN_TOUCH, 0);
148 input_sync(data->input_dev); 260 input_sync(data->input_dev);
149 break; 261 break;
150
151 case EVENT_FIFO_END: 262 case EVENT_FIFO_END:
152 break; 263 break;
153 } 264 }
154 } 265 }
155out: 266out:
@@ -160,18 +271,37 @@ static void max11801_ts_phy_init(struct max11801_data *data)
160{ 271{
161 struct i2c_client *client = data->client; 272 struct i2c_client *client = data->client;
162 273
163 /* Average X,Y, take 16 samples, average eight media sample */ 274 max11801_client = client;
275 /* Average X,Y, take 16 samples average eight media sample */
164 max11801_write_reg(client, MESURE_AVER_CONF_REG, 0xff); 276 max11801_write_reg(client, MESURE_AVER_CONF_REG, 0xff);
165 /* X,Y panel setup time set to 20us */ 277 /* X,Y panel setup time set to 20us */
166 max11801_write_reg(client, PANEL_SETUPTIME_CONF_REG, 0x11); 278 max11801_write_reg(client, PANEL_SETUPTIME_CONF_REG, 0x11);
167 /* Rough pullup time (2uS), Fine pullup time (10us) */ 279 /* Rough pullup time (2uS), Fine pullup time (10us) */
168 max11801_write_reg(client, TOUCH_DETECT_PULLUP_CONF_REG, 0x10); 280 max11801_write_reg(client, TOUCH_DETECT_PULLUP_CONF_REG, 0x10);
169 /* Auto mode init period = 5ms , scan period = 5ms*/ 281 /* Auto mode init period = 5ms, scan period = 5ms */
170 max11801_write_reg(client, AUTO_MODE_TIME_CONF_REG, 0xaa); 282 max11801_write_reg(client, AUTO_MODE_TIME_CONF_REG, 0xaa);
171 /* Aperture X,Y set to +- 4LSB */ 283 /* Aperture X,Y set to +- 4LSB */
172 max11801_write_reg(client, APERTURE_CONF_REG, 0x33); 284 max11801_write_reg(client, APERTURE_CONF_REG, 0x33);
173 /* Enable Power, enable Automode, enable Aperture, enable Average X,Y */ 285 /*
174 max11801_write_reg(client, OP_MODE_CONF_REG, 0x36); 286 * Enable Power, enable Automode, enable Aperture,
287 * enable Average X,Y
288 */
289 if (!max11801_workmode)
290 max11801_write_reg(client, OP_MODE_CONF_REG, 0x36);
291 else {
292 max11801_write_reg(client, OP_MODE_CONF_REG, 0x16);
293 /*
294 * Delay initial=1ms, Sampling time 2us
295 * Averaging sample depth 2
296 * samples, Resolution 12bit
297 */
298 max11801_write_reg(client, AUX_MESURE_CONF_REG, 0x76);
299 /*
300 * Use edge interrupt with
301 * direct conversion mode
302 */
303 max11801_write_reg(client, GENERNAL_CONF_REG, 0xf3);
304 }
175} 305}
176 306
177static int max11801_ts_probe(struct i2c_client *client, 307static int max11801_ts_probe(struct i2c_client *client,
@@ -180,6 +310,7 @@ static int max11801_ts_probe(struct i2c_client *client,
180 struct max11801_data *data; 310 struct max11801_data *data;
181 struct input_dev *input_dev; 311 struct input_dev *input_dev;
182 int error; 312 int error;
313 struct device_node *of_node = client->dev.of_node;
183 314
184 data = kzalloc(sizeof(struct max11801_data), GFP_KERNEL); 315 data = kzalloc(sizeof(struct max11801_data), GFP_KERNEL);
185 input_dev = input_allocate_device(); 316 input_dev = input_allocate_device();
@@ -203,11 +334,14 @@ static int max11801_ts_probe(struct i2c_client *client,
203 input_set_abs_params(input_dev, ABS_Y, 0, MAX11801_MAX_Y, 0, 0); 334 input_set_abs_params(input_dev, ABS_Y, 0, MAX11801_MAX_Y, 0, 0);
204 input_set_drvdata(input_dev, data); 335 input_set_drvdata(input_dev, data);
205 336
337 if (of_property_read_u32(of_node, "work-mode", &max11801_workmode))
338 max11801_workmode = *(int *)(client->dev).platform_data;
339
206 max11801_ts_phy_init(data); 340 max11801_ts_phy_init(data);
207 341
208 error = request_threaded_irq(client->irq, NULL, max11801_ts_interrupt, 342 error = request_threaded_irq(client->irq, NULL, max11801_ts_interrupt,
209 IRQF_TRIGGER_LOW | IRQF_ONESHOT, 343 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
210 "max11801_ts", data); 344 "max11801_ts", data);
211 if (error) { 345 if (error) {
212 dev_err(&client->dev, "Failed to register interrupt\n"); 346 dev_err(&client->dev, "Failed to register interrupt\n");
213 goto err_free_mem; 347 goto err_free_mem;
@@ -245,10 +379,17 @@ static const struct i2c_device_id max11801_ts_id[] = {
245}; 379};
246MODULE_DEVICE_TABLE(i2c, max11801_ts_id); 380MODULE_DEVICE_TABLE(i2c, max11801_ts_id);
247 381
382static const struct of_device_id max11801_ts_dt_ids[] = {
383 { .compatible = "maxim,max11801", },
384 { /* sentinel */ }
385};
386MODULE_DEVICE_TABLE(of, max11801_ts_dt_ids);
387
248static struct i2c_driver max11801_ts_driver = { 388static struct i2c_driver max11801_ts_driver = {
249 .driver = { 389 .driver = {
250 .name = "max11801_ts", 390 .name = "max11801_ts",
251 .owner = THIS_MODULE, 391 .owner = THIS_MODULE,
392 .of_match_table = max11801_ts_dt_ids,
252 }, 393 },
253 .id_table = max11801_ts_id, 394 .id_table = max11801_ts_id,
254 .probe = max11801_ts_probe, 395 .probe = max11801_ts_probe,