blob: ab159457dff5fc3594b56aa7093eb89698c8c10e [file] [log] [blame]
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -070013#include <linux/kernel.h>
Steve Mucklef132c6c2012-06-06 18:30:57 -070014#include <linux/module.h>
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -070015#include <linux/init.h>
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -070016#include <linux/fs.h>
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -070017#include <linux/mutex.h>
18#include <linux/err.h>
19#include <linux/slab.h>
20#include <linux/gpio.h>
21#include <linux/hwmon.h>
22#include <linux/delay.h>
23#include <linux/epm_adc.h>
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -070024#include <linux/uaccess.h>
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -070025#include <linux/spi/spi.h>
26#include <linux/hwmon-sysfs.h>
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -070027#include <linux/miscdevice.h>
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -070028#include <linux/platform_device.h>
29
30#define EPM_ADC_DRIVER_NAME "epm_adc"
31#define EPM_ADC_MAX_FNAME 20
32#define EPM_ADC_CONVERSION_DELAY 100 /* milliseconds */
33/* Command Bits */
34#define EPM_ADC_ADS_SPI_BITS_PER_WORD 8
35#define EPM_ADC_ADS_DATA_READ_CMD (0x1 << 5)
36#define EPM_ADC_ADS_REG_READ_CMD (0x2 << 5)
37#define EPM_ADC_ADS_REG_WRITE_CMD (0x3 << 5)
38#define EPM_ADC_ADS_PULSE_CONVERT_CMD (0x4 << 5)
39#define EPM_ADC_ADS_MULTIPLE_REG_ACCESS (0x1 << 4)
40/* Register map */
41#define EPM_ADC_ADS_CONFIG0_REG_ADDR 0x0
42#define EPM_ADC_ADS_CONFIG1_REG_ADDR 0x1
43#define EPM_ADC_ADS_MUXSG0_REG_ADDR 0x4
44#define EPM_ADC_ADS_MUXSG1_REG_ADDR 0x5
45/* Register map default data */
46#define EPM_ADC_ADS_REG0_DEFAULT 0x2
47#define EPM_ADC_ADS_REG1_DEFAULT 0x52
48#define EPM_ADC_ADS_CHANNEL_DATA_CHID 0x1f
49/* Channel ID */
50#define EPM_ADC_ADS_CHANNEL_OFFSET 0x18
51#define EPM_ADC_ADS_CHANNEL_VCC 0x1a
52#define EPM_ADC_ADS_CHANNEL_TEMP 0x1b
53#define EPM_ADC_ADS_CHANNEL_GAIN 0x1c
54#define EPM_ADC_ADS_CHANNEL_REF 0x1d
55/* Scaling data co-efficients */
56#define EPM_ADC_SCALE_MILLI 1000
57#define EPM_ADC_SCALE_CODE_VOLTS 3072
58#define EPM_ADC_SCALE_CODE_GAIN 30720
59#define EPM_ADC_TEMP_SENSOR_COEFF 394
60#define EPM_ADC_TEMP_TO_DEGC_COEFF 168000
61#define EPM_ADC_CHANNEL_AIN_OFFSET 8
62#define EPM_ADC_MAX_NEGATIVE_SCALE_CODE 0x8000
63#define EPM_ADC_NEG_LSB_CODE 0xffff
64#define EPM_ADC_VREF_CODE 0x7800
65#define EPM_ADC_MILLI_VOLTS_SOURCE 4750
66#define EPM_ADC_SCALE_FACTOR 64
67#define GPIO_EPM_GLOBAL_ENABLE 86
68#define EPM_ADC_CONVERSION_TIME_MIN 50000
69#define EPM_ADC_CONVERSION_TIME_MAX 51000
70
Yan He2af37f12012-08-31 11:09:36 -070071#define EPM_SPI_NOR_CS_N_GPIO 53
72
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -070073struct epm_adc_drv {
74 struct platform_device *pdev;
75 struct device *hwmon;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -070076 struct spi_device *epm_spi_client;
77 struct mutex conv_lock;
78 uint32_t bus_id;
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -070079 struct miscdevice misc;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -070080};
81
82static struct epm_adc_drv *epm_adc_drv;
83static struct i2c_board_info *epm_i2c_info;
84static bool epm_adc_first_request;
85static int epm_gpio_expander_base_addr;
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -070086static bool epm_adc_expander_register;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -070087
88#define GPIO_EPM_EXPANDER_IO0 epm_gpio_expander_base_addr
89#define GPIO_PWR_MON_ENABLE (GPIO_EPM_EXPANDER_IO0 + 1)
90#define GPIO_ADC1_PWDN_N (GPIO_PWR_MON_ENABLE + 1)
91#define GPIO_PWR_MON_RESET_N (GPIO_ADC1_PWDN_N + 1)
92#define GPIO_EPM_SPI_ADC1_CS_N (GPIO_PWR_MON_RESET_N + 1)
93#define GPIO_PWR_MON_START (GPIO_EPM_SPI_ADC1_CS_N + 1)
94#define GPIO_ADC1_DRDY_N (GPIO_PWR_MON_START + 1)
95#define GPIO_ADC2_PWDN_N (GPIO_ADC1_DRDY_N + 1)
96#define GPIO_EPM_SPI_ADC2_CS_N (GPIO_ADC2_PWDN_N + 1)
97#define GPIO_ADC2_DRDY_N (GPIO_EPM_SPI_ADC2_CS_N + 1)
98
99static int epm_adc_i2c_expander_register(void)
100{
101 int rc = 0;
102 static struct i2c_adapter *i2c_adap;
103 static struct i2c_client *epm_i2c_client;
104
105 rc = gpio_request(GPIO_EPM_GLOBAL_ENABLE, "EPM_GLOBAL_EN");
106 if (!rc) {
107 gpio_direction_output(GPIO_EPM_GLOBAL_ENABLE, 1);
108 } else {
109 pr_err("%s: Configure EPM_GLOBAL_EN Failed\n", __func__);
110 return rc;
111 }
112
113 usleep_range(EPM_ADC_CONVERSION_TIME_MIN,
114 EPM_ADC_CONVERSION_TIME_MAX);
115
116 i2c_adap = i2c_get_adapter(epm_adc_drv->bus_id);
117 if (i2c_adap == NULL) {
118 pr_err("%s: i2c_get_adapter() failed\n", __func__);
119 return -EINVAL;
120 }
121
122 usleep_range(EPM_ADC_CONVERSION_TIME_MIN,
123 EPM_ADC_CONVERSION_TIME_MAX);
124
125 epm_i2c_client = i2c_new_device(i2c_adap, epm_i2c_info);
126 if (IS_ERR(epm_i2c_client)) {
127 pr_err("Error with i2c epm device register\n");
128 return -ENODEV;
129 }
130
131 epm_adc_first_request = false;
132
133 return 0;
134}
135
136static int epm_adc_gpio_configure_expander_enable(void)
137{
138 int rc = 0;
139
Yan He2af37f12012-08-31 11:09:36 -0700140 rc = gpio_request(EPM_SPI_NOR_CS_N_GPIO, "SPI_NOR_CS_N");
141 if (!rc)
142 gpio_direction_output(EPM_SPI_NOR_CS_N_GPIO, 1);
143 else {
144 pr_err("Configure spi nor Failed\n");
145 return -EINVAL;
146 }
147
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700148 if (epm_adc_first_request) {
149 rc = gpio_request(GPIO_EPM_GLOBAL_ENABLE, "EPM_GLOBAL_EN");
150 if (!rc) {
151 gpio_direction_output(GPIO_EPM_GLOBAL_ENABLE, 1);
152 } else {
153 pr_err("%s: Configure EPM_GLOBAL_EN Failed\n",
154 __func__);
155 return rc;
156 }
157 } else {
158 epm_adc_first_request = true;
159 }
160
161 usleep_range(EPM_ADC_CONVERSION_TIME_MIN,
162 EPM_ADC_CONVERSION_TIME_MAX);
163
164 rc = gpio_request(GPIO_PWR_MON_ENABLE, "GPIO_PWR_MON_ENABLE");
165 if (!rc) {
166 rc = gpio_direction_output(GPIO_PWR_MON_ENABLE, 1);
167 if (rc) {
168 pr_err("%s: Set GPIO_PWR_MON_ENABLE failed\n",
169 __func__);
170 return rc;
171 }
172 } else {
173 pr_err("%s: gpio_request GPIO_PWR_MON_ENABLE failed\n",
174 __func__);
175 return rc;
176 }
177
178 rc = gpio_request(GPIO_ADC1_PWDN_N, "GPIO_ADC1_PWDN_N");
179 if (!rc) {
180 rc = gpio_direction_output(GPIO_ADC1_PWDN_N, 1);
181 if (rc) {
182 pr_err("%s: Set GPIO_ADC1_PWDN_N failed\n", __func__);
183 return rc;
184 }
185 } else {
186 pr_err("%s: gpio_request GPIO_ADC1_PWDN_N failed\n", __func__);
187 return rc;
188 }
189
190 rc = gpio_request(GPIO_ADC2_PWDN_N, "GPIO_ADC2_PWDN_N");
191 if (!rc) {
192 rc = gpio_direction_output(GPIO_ADC2_PWDN_N, 1);
193 if (rc) {
194 pr_err("%s: Set GPIO_ADC2_PWDN_N failed\n",
195 __func__);
196 return rc;
197 }
198 } else {
199 pr_err("%s: gpio_request GPIO_ADC2_PWDN_N failed\n",
200 __func__);
201 return rc;
202 }
203
204 rc = gpio_request(GPIO_EPM_SPI_ADC1_CS_N, "GPIO_EPM_SPI_ADC1_CS_N");
205 if (!rc) {
206 rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 1);
207 if (rc) {
208 pr_err("%s:Set GPIO_EPM_SPI_ADC1_CS_N failed\n",
209 __func__);
210 return rc;
211 }
212 } else {
213 pr_err("%s: gpio_request GPIO_EPM_SPI_ADC1_CS_N failed\n",
214 __func__);
215 return rc;
216 }
217
218 rc = gpio_request(GPIO_EPM_SPI_ADC2_CS_N,
219 "GPIO_EPM_SPI_ADC2_CS_N");
220 if (!rc) {
221 rc = gpio_direction_output(GPIO_EPM_SPI_ADC2_CS_N, 1);
222 if (rc) {
223 pr_err("%s: Set GPIO_EPM_SPI_ADC2_CS_N "
224 "failed\n", __func__);
225 return rc;
226 }
227 } else {
228 pr_err("%s: gpio_request GPIO_EPM_SPI_ADC2_CS_N "
229 "failed\n", __func__);
230 return rc;
231 }
232
233 rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 0);
234 if (rc) {
235 pr_err("%s:Reset GPIO_EPM_SPI_ADC1_CS_N failed\n", __func__);
236 return rc;
237 }
238
239 rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 1);
240 if (rc) {
241 pr_err("%s: Set GPIO_EPM_SPI_ADC1_CS_N failed\n", __func__);
242 return rc;
243 }
244
245 rc = gpio_request(GPIO_PWR_MON_START, "GPIO_PWR_MON_START");
246 if (!rc) {
247 rc = gpio_direction_output(GPIO_PWR_MON_START, 0);
248 if (rc) {
249 pr_err("%s: Reset GPIO_PWR_MON_START failed\n",
250 __func__);
251 return rc;
252 }
253 } else {
254 pr_err("%s: gpio_request GPIO_PWR_MON_START failed\n",
255 __func__);
256 return rc;
257 }
258
259 rc = gpio_request(GPIO_PWR_MON_RESET_N, "GPIO_PWR_MON_RESET_N");
260 if (!rc) {
261 rc = gpio_direction_output(GPIO_PWR_MON_RESET_N, 0);
262 if (rc) {
263 pr_err("%s: Reset GPIO_PWR_MON_RESET_N failed\n",
264 __func__);
265 return rc;
266 }
267 } else {
268 pr_err("%s: gpio_request GPIO_PWR_MON_RESET_N failed\n",
269 __func__);
270 return rc;
271 }
272
273 rc = gpio_direction_output(GPIO_PWR_MON_RESET_N, 1);
274 if (rc) {
275 pr_err("%s: Set GPIO_PWR_MON_RESET_N failed\n", __func__);
276 return rc;
277 }
278
279 rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 0);
280 if (rc) {
281 pr_err("%s:Reset GPIO_EPM_SPI_ADC1_CS_N failed\n", __func__);
282 return rc;
283 }
284 return rc;
285}
286
287static int epm_adc_gpio_configure_expander_disable(void)
288{
289 int rc = 0;
290 gpio_free(GPIO_PWR_MON_ENABLE);
291 gpio_free(GPIO_ADC1_PWDN_N);
292 gpio_free(GPIO_ADC2_PWDN_N);
293 gpio_free(GPIO_EPM_SPI_ADC1_CS_N);
294 gpio_free(GPIO_EPM_SPI_ADC2_CS_N);
295 gpio_free(GPIO_PWR_MON_START);
296 gpio_free(GPIO_PWR_MON_RESET_N);
297 rc = gpio_direction_output(GPIO_EPM_GLOBAL_ENABLE, 0);
298 if (rc)
299 pr_debug("%s: Disable EPM_GLOBAL_EN Failed\n", __func__);
300 gpio_free(GPIO_EPM_GLOBAL_ENABLE);
301 return rc;
302}
303
304static int epm_adc_spi_chip_select(int32_t id)
305{
306 int rc = 0;
307 if (id == 0) {
308 rc = gpio_direction_output(GPIO_EPM_SPI_ADC2_CS_N, 1);
309 if (rc) {
310 pr_err("%s:Disable SPI_ADC2_CS failed",
311 __func__);
312 return rc;
313 }
314
315 rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 0);
316 if (rc) {
317 pr_err("%s:Enable SPI_ADC1_CS failed", __func__);
318 return rc;
319 }
320 } else if (id == 1) {
321 rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 1);
322 if (rc) {
323 pr_err("%s:Disable SPI_ADC1_CS failed", __func__);
324 return rc;
325 }
326 rc = gpio_direction_output(GPIO_EPM_SPI_ADC2_CS_N, 0);
327 if (rc) {
328 pr_err("%s:Enable SPI_ADC2_CS failed", __func__);
329 return rc;
330 }
331 } else {
332 rc = -EFAULT;
333 }
334 return rc;
335}
336
337static int epm_adc_ads_spi_write(struct epm_adc_drv *epm_adc,
338 uint8_t addr, uint8_t val)
339{
340 struct spi_message m;
341 struct spi_transfer t;
342 char tx_buf[2];
343 int rc = 0;
344
345 spi_setup(epm_adc->epm_spi_client);
346
347 memset(&t, 0, sizeof t);
348 memset(tx_buf, 0, sizeof tx_buf);
349 t.tx_buf = tx_buf;
350 spi_message_init(&m);
351 spi_message_add_tail(&t, &m);
352
353 tx_buf[0] = EPM_ADC_ADS_REG_WRITE_CMD | addr;
354 tx_buf[1] = val;
355
356 t.len = sizeof(tx_buf);
357 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
358
359 rc = spi_sync(epm_adc->epm_spi_client, &m);
360
361 return rc;
362}
363
364static int epm_adc_init_ads(struct epm_adc_drv *epm_adc)
365{
366 int rc = 0;
367
368 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_CONFIG0_REG_ADDR,
369 EPM_ADC_ADS_REG0_DEFAULT);
370 if (rc)
371 return rc;
372
373 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_CONFIG1_REG_ADDR,
374 EPM_ADC_ADS_REG1_DEFAULT);
375 if (rc)
376 return rc;
377 return rc;
378}
379
380static int epm_adc_ads_pulse_convert(struct epm_adc_drv *epm_adc)
381{
382 struct spi_message m;
383 struct spi_transfer t;
384 char tx_buf[1];
385 int rc = 0;
386
387 spi_setup(epm_adc->epm_spi_client);
388
389 memset(&t, 0, sizeof t);
390 memset(tx_buf, 0, sizeof tx_buf);
391 t.tx_buf = tx_buf;
392 spi_message_init(&m);
393 spi_message_add_tail(&t, &m);
394
395 tx_buf[0] = EPM_ADC_ADS_PULSE_CONVERT_CMD;
396 t.len = sizeof(tx_buf);
397 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
398
399 rc = spi_sync(epm_adc->epm_spi_client, &m);
400
401 return rc;
402}
403
404static int epm_adc_ads_read_data(struct epm_adc_drv *epm_adc, char *adc_data)
405{
406 struct spi_message m;
407 struct spi_transfer t;
408 char tx_buf[4], rx_buf[4];
409 int rc = 0;
410
411 spi_setup(epm_adc->epm_spi_client);
412
413 memset(&t, 0, sizeof t);
414 memset(tx_buf, 0, sizeof tx_buf);
415 memset(rx_buf, 0, sizeof tx_buf);
416 t.tx_buf = tx_buf;
417 t.rx_buf = rx_buf;
418 spi_message_init(&m);
419 spi_message_add_tail(&t, &m);
420
421 tx_buf[0] = EPM_ADC_ADS_DATA_READ_CMD |
422 EPM_ADC_ADS_MULTIPLE_REG_ACCESS;
423
424 t.len = sizeof(tx_buf);
425 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
426
427 rc = spi_sync(epm_adc->epm_spi_client, &m);
428 if (rc)
429 return rc;
430
431 rc = spi_sync(epm_adc->epm_spi_client, &m);
432 if (rc)
433 return rc;
434
435 rc = spi_sync(epm_adc->epm_spi_client, &m);
436 if (rc)
437 return rc;
438
439 adc_data[0] = rx_buf[1];
440 adc_data[1] = rx_buf[2];
441 adc_data[2] = rx_buf[3];
442
443 return rc;
444}
445
446static int epm_adc_hw_init(struct epm_adc_drv *epm_adc)
447{
448 int rc = 0;
449
450 mutex_lock(&epm_adc->conv_lock);
451 rc = epm_adc_gpio_configure_expander_enable();
452 if (rc != 0) {
453 pr_err("epm gpio configure expander failed, rc = %d\n", rc);
454 goto epm_adc_hw_init_err;
455 }
456 rc = epm_adc_init_ads(epm_adc);
457 if (rc) {
458 pr_err("epm_adc_init_ads failed, rc=%d\n", rc);
459 goto epm_adc_hw_init_err;
460 }
461
462epm_adc_hw_init_err:
463 mutex_unlock(&epm_adc->conv_lock);
464 return rc;
465}
466
467static int epm_adc_hw_deinit(struct epm_adc_drv *epm_adc)
468{
469 int rc = 0;
470
471 mutex_lock(&epm_adc->conv_lock);
472 rc = epm_adc_gpio_configure_expander_disable();
473 if (rc != 0) {
474 pr_err("epm gpio configure expander disable failed,"
475 " rc = %d\n", rc);
476 goto epm_adc_hw_deinit_err;
477 }
478
479epm_adc_hw_deinit_err:
480 mutex_unlock(&epm_adc->conv_lock);
481 return rc;
482}
483
484static int epm_adc_ads_scale_result(struct epm_adc_drv *epm_adc,
485 uint8_t *adc_raw_data, struct epm_chan_request *conv)
486{
487 uint32_t channel_num;
488 int16_t sign_bit;
489 struct epm_adc_platform_data *pdata = epm_adc->pdev->dev.platform_data;
490 uint32_t chan_idx = (conv->device_idx * pdata->chan_per_adc) +
491 conv->channel_idx;
Yan He2af37f12012-08-31 11:09:36 -0700492 int64_t *adc_scaled_data = 0;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700493
494 /* Get the channel number */
495 channel_num = (adc_raw_data[0] & EPM_ADC_ADS_CHANNEL_DATA_CHID);
496 sign_bit = 1;
497 /* This is the 16-bit raw data */
498 *adc_scaled_data = ((adc_raw_data[1] << 8) | adc_raw_data[2]);
499 /* Obtain the internal system reading */
500 if (channel_num == EPM_ADC_ADS_CHANNEL_VCC) {
501 *adc_scaled_data *= EPM_ADC_SCALE_MILLI;
Yan He2af37f12012-08-31 11:09:36 -0700502 do_div(*adc_scaled_data, EPM_ADC_SCALE_CODE_VOLTS);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700503 } else if (channel_num == EPM_ADC_ADS_CHANNEL_GAIN) {
Yan He2af37f12012-08-31 11:09:36 -0700504 do_div(*adc_scaled_data, EPM_ADC_SCALE_CODE_GAIN);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700505 } else if (channel_num == EPM_ADC_ADS_CHANNEL_REF) {
506 *adc_scaled_data *= EPM_ADC_SCALE_MILLI;
Yan He2af37f12012-08-31 11:09:36 -0700507 do_div(*adc_scaled_data, EPM_ADC_SCALE_CODE_VOLTS);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700508 } else if (channel_num == EPM_ADC_ADS_CHANNEL_TEMP) {
509 /* Convert Code to micro-volts */
510 /* Use this formula to get the temperature reading */
511 *adc_scaled_data -= EPM_ADC_TEMP_TO_DEGC_COEFF;
Yan He2af37f12012-08-31 11:09:36 -0700512 do_div(*adc_scaled_data, EPM_ADC_TEMP_SENSOR_COEFF);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700513 } else if (channel_num == EPM_ADC_ADS_CHANNEL_OFFSET) {
514 /* The offset should be zero */
515 pr_debug("%s: ADC Channel Offset\n", __func__);
516 return -EFAULT;
517 } else {
518 channel_num -= EPM_ADC_CHANNEL_AIN_OFFSET;
519 /*
520 * Conversion for the adc channels.
521 * mvVRef is in milli-volts and resistorValue is in micro-ohms.
522 * Hence, I = V/R gives us current in kilo-amps.
523 */
524 if (*adc_scaled_data & EPM_ADC_MAX_NEGATIVE_SCALE_CODE) {
525 sign_bit = -1;
526 *adc_scaled_data = (~*adc_scaled_data
527 & EPM_ADC_NEG_LSB_CODE);
528 }
529 if (*adc_scaled_data != 0) {
530 *adc_scaled_data *= EPM_ADC_SCALE_FACTOR;
531 /* Device is calibrated for 1LSB = VREF/7800h.*/
532 *adc_scaled_data *= EPM_ADC_MILLI_VOLTS_SOURCE;
Yan He2af37f12012-08-31 11:09:36 -0700533 do_div(*adc_scaled_data, EPM_ADC_VREF_CODE);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700534 /* Data will now be in micro-volts.*/
535 *adc_scaled_data *= EPM_ADC_SCALE_MILLI;
536 /* Divide by amplifier gain value.*/
Yan He2af37f12012-08-31 11:09:36 -0700537 do_div(*adc_scaled_data, pdata->channel[chan_idx].gain);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700538 /* Data will now be in nano-volts.*/
Yan He2af37f12012-08-31 11:09:36 -0700539 do_div(*adc_scaled_data, EPM_ADC_SCALE_FACTOR);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700540 *adc_scaled_data *= EPM_ADC_SCALE_MILLI;
541 /* Data is now in micro-amps.*/
Yan He2af37f12012-08-31 11:09:36 -0700542 do_div(*adc_scaled_data,
543 pdata->channel[chan_idx].resistorValue);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700544 /* Set the sign bit for lekage current. */
545 *adc_scaled_data *= sign_bit;
546 }
547 }
Yan He2af37f12012-08-31 11:09:36 -0700548 conv->physical = (int32_t) *adc_scaled_data;
549
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700550 return 0;
551}
552
553static int epm_adc_blocking_conversion(struct epm_adc_drv *epm_adc,
554 struct epm_chan_request *conv)
555{
556 struct epm_adc_platform_data *pdata = epm_adc->pdev->dev.platform_data;
557 int32_t channel_num = 0, mux_chan_idx = 0;
558 char adc_data[3];
559 int rc = 0;
560
561 mutex_lock(&epm_adc->conv_lock);
562
563 rc = epm_adc_spi_chip_select(conv->device_idx);
564 if (rc) {
565 pr_err("epm_adc_chip_select failed, rc=%d\n", rc);
566 goto conv_err;
567 }
568
569 if (conv->channel_idx < pdata->chan_per_mux) {
570 /* Reset MUXSG1_REGISTER */
571 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_MUXSG1_REG_ADDR,
572 0x0);
573 if (rc)
574 goto conv_err;
575
576 mux_chan_idx = 1 << conv->channel_idx;
577 /* Select Channel index in MUXSG0_REGISTER */
578 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_MUXSG0_REG_ADDR,
579 mux_chan_idx);
580 if (rc)
581 goto conv_err;
582 } else {
583 /* Reset MUXSG0_REGISTER */
584 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_MUXSG0_REG_ADDR,
585 0x0);
586 if (rc)
587 goto conv_err;
588
589 mux_chan_idx = 1 << (conv->channel_idx - pdata->chan_per_mux);
590 /* Select Channel index in MUXSG1_REGISTER */
591 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_MUXSG1_REG_ADDR,
592 mux_chan_idx);
593 if (rc)
594 goto conv_err;
595 }
596
597 rc = epm_adc_ads_pulse_convert(epm_adc);
598 if (rc) {
599 pr_err("epm_adc_ads_pulse_convert failed, rc=%d\n", rc);
600 goto conv_err;
601 }
602
603 rc = epm_adc_ads_read_data(epm_adc, adc_data);
604 if (rc) {
605 pr_err("epm_adc_ads_read_data failed, rc=%d\n", rc);
606 goto conv_err;
607 }
608
609 channel_num = (adc_data[0] & EPM_ADC_ADS_CHANNEL_DATA_CHID);
610 pr_debug("ADC data Read: adc_data =%d, %d, %d\n",
611 adc_data[0], adc_data[1], adc_data[2]);
612
613 epm_adc_ads_scale_result(epm_adc, (uint8_t *)adc_data, conv);
614
615 pr_debug("channel_num(0x) = %x, scaled_data = %d\n",
616 (channel_num - EPM_ADC_ADS_SPI_BITS_PER_WORD),
617 conv->physical);
618conv_err:
619 mutex_unlock(&epm_adc->conv_lock);
620 return rc;
621}
622
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -0700623static long epm_adc_ioctl(struct file *file, unsigned int cmd,
624 unsigned long arg)
625{
626 struct epm_adc_drv *epm_adc = epm_adc_drv;
627
628 switch (cmd) {
629 case EPM_ADC_REQUEST:
630 {
631 struct epm_chan_request conv;
632 int rc;
633
634 if (copy_from_user(&conv, (void __user *)arg,
635 sizeof(struct epm_chan_request)))
636 return -EFAULT;
637
638 rc = epm_adc_blocking_conversion(epm_adc, &conv);
639 if (rc) {
640 pr_err("Failed EPM conversion:%d\n", rc);
641 return rc;
642 }
643
644 if (copy_to_user((void __user *)arg, &conv,
645 sizeof(struct epm_chan_request)))
646 return -EFAULT;
647 break;
648 }
649 case EPM_ADC_INIT:
650 {
651 uint32_t result;
652 if (!epm_adc_expander_register) {
653 result = epm_adc_i2c_expander_register();
654 if (result) {
655 pr_err("Failed i2c register:%d\n",
656 result);
657 return result;
658 }
659 epm_adc_expander_register = true;
660 }
661
662 result = epm_adc_hw_init(epm_adc_drv);
663
664 if (copy_to_user((void __user *)arg, &result,
665 sizeof(uint32_t)))
666 return -EFAULT;
667 break;
668 }
669 case EPM_ADC_DEINIT:
670 {
671 uint32_t result;
672 result = epm_adc_hw_deinit(epm_adc_drv);
673
674 if (copy_to_user((void __user *)arg, &result,
675 sizeof(uint32_t)))
676 return -EFAULT;
677 break;
678 }
679 default:
680 return -EINVAL;
681 }
682
683 return 0;
684}
685
686const struct file_operations epm_adc_fops = {
687 .unlocked_ioctl = epm_adc_ioctl,
688};
689
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700690static ssize_t epm_adc_show_in(struct device *dev,
691 struct device_attribute *devattr, char *buf)
692{
693 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
694 struct epm_adc_drv *epm_adc = dev_get_drvdata(dev);
695 struct epm_adc_platform_data *pdata = epm_adc->pdev->dev.platform_data;
696 struct epm_chan_request conv;
697 int rc = 0;
698
699 conv.device_idx = attr->index / pdata->chan_per_adc;
700 conv.channel_idx = attr->index % pdata->chan_per_adc;
701 conv.physical = 0;
702 pr_debug("%s: device_idx=%d channel_idx=%d", __func__, conv.device_idx,
703 conv.channel_idx);
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -0700704 if (!epm_adc_expander_register) {
705 rc = epm_adc_i2c_expander_register();
706 if (rc) {
707 pr_err("I2C expander register failed:%d\n", rc);
708 return rc;
709 }
710 epm_adc_expander_register = true;
711 }
712
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700713 rc = epm_adc_hw_init(epm_adc);
714 if (rc) {
715 pr_err("%s: epm_adc_hw_init() failed, rc = %d",
716 __func__, rc);
717 return 0;
718 }
719
720 rc = epm_adc_blocking_conversion(epm_adc, &conv);
721 if (rc) {
722 pr_err("%s: epm_adc_blocking_conversion() failed, rc = %d\n",
723 __func__, rc);
724 return 0;
725 }
726 rc = epm_adc_hw_deinit(epm_adc);
727 if (rc) {
728 pr_err("%s: epm_adc_hw_deinit() failed, rc = %d",
729 __func__, rc);
730 return 0;
731 }
732
733 return snprintf(buf, 16, "Result: %d\n", conv.physical);
734}
735
Stephen Boydaeaf2ad2012-07-03 14:33:25 -0700736static struct sensor_device_attribute epm_adc_in_attrs[] = {
737 SENSOR_ATTR(ads0_chan0, S_IRUGO, epm_adc_show_in, NULL, 0),
738 SENSOR_ATTR(ads0_chan1, S_IRUGO, epm_adc_show_in, NULL, 1),
739 SENSOR_ATTR(ads0_chan2, S_IRUGO, epm_adc_show_in, NULL, 2),
740 SENSOR_ATTR(ads0_chan3, S_IRUGO, epm_adc_show_in, NULL, 3),
741 SENSOR_ATTR(ads0_chan4, S_IRUGO, epm_adc_show_in, NULL, 4),
742 SENSOR_ATTR(ads0_chan5, S_IRUGO, epm_adc_show_in, NULL, 5),
743 SENSOR_ATTR(ads0_chan6, S_IRUGO, epm_adc_show_in, NULL, 6),
744 SENSOR_ATTR(ads0_chan7, S_IRUGO, epm_adc_show_in, NULL, 7),
745 SENSOR_ATTR(ads0_chan8, S_IRUGO, epm_adc_show_in, NULL, 8),
746 SENSOR_ATTR(ads0_chan9, S_IRUGO, epm_adc_show_in, NULL, 9),
747 SENSOR_ATTR(ads0_chan10, S_IRUGO, epm_adc_show_in, NULL, 10),
748 SENSOR_ATTR(ads0_chan11, S_IRUGO, epm_adc_show_in, NULL, 11),
749 SENSOR_ATTR(ads0_chan12, S_IRUGO, epm_adc_show_in, NULL, 12),
750 SENSOR_ATTR(ads0_chan13, S_IRUGO, epm_adc_show_in, NULL, 13),
751 SENSOR_ATTR(ads0_chan14, S_IRUGO, epm_adc_show_in, NULL, 14),
752 SENSOR_ATTR(ads0_chan15, S_IRUGO, epm_adc_show_in, NULL, 15),
753 SENSOR_ATTR(ads1_chan0, S_IRUGO, epm_adc_show_in, NULL, 16),
754 SENSOR_ATTR(ads1_chan1, S_IRUGO, epm_adc_show_in, NULL, 17),
755 SENSOR_ATTR(ads1_chan2, S_IRUGO, epm_adc_show_in, NULL, 18),
756 SENSOR_ATTR(ads1_chan3, S_IRUGO, epm_adc_show_in, NULL, 19),
757 SENSOR_ATTR(ads1_chan4, S_IRUGO, epm_adc_show_in, NULL, 20),
758 SENSOR_ATTR(ads1_chan5, S_IRUGO, epm_adc_show_in, NULL, 21),
759 SENSOR_ATTR(ads1_chan6, S_IRUGO, epm_adc_show_in, NULL, 22),
760 SENSOR_ATTR(ads1_chan7, S_IRUGO, epm_adc_show_in, NULL, 23),
761 SENSOR_ATTR(ads1_chan8, S_IRUGO, epm_adc_show_in, NULL, 24),
762 SENSOR_ATTR(ads1_chan9, S_IRUGO, epm_adc_show_in, NULL, 25),
763 SENSOR_ATTR(ads1_chan10, S_IRUGO, epm_adc_show_in, NULL, 26),
764 SENSOR_ATTR(ads1_chan11, S_IRUGO, epm_adc_show_in, NULL, 27),
765 SENSOR_ATTR(ads1_chan12, S_IRUGO, epm_adc_show_in, NULL, 28),
766 SENSOR_ATTR(ads1_chan13, S_IRUGO, epm_adc_show_in, NULL, 29),
767 SENSOR_ATTR(ads1_chan14, S_IRUGO, epm_adc_show_in, NULL, 30),
768 SENSOR_ATTR(ads1_chan15, S_IRUGO, epm_adc_show_in, NULL, 31),
769};
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700770
771static int __devinit epm_adc_init_hwmon(struct platform_device *pdev,
772 struct epm_adc_drv *epm_adc)
773{
774 struct epm_adc_platform_data *pdata = pdev->dev.platform_data;
Stephen Boydaeaf2ad2012-07-03 14:33:25 -0700775 int i, rc, num_chans = pdata->num_channels;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700776
Stephen Boydaeaf2ad2012-07-03 14:33:25 -0700777 for (i = 0; i < num_chans; i++) {
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700778 rc = device_create_file(&pdev->dev,
Stephen Boydaeaf2ad2012-07-03 14:33:25 -0700779 &epm_adc_in_attrs[i].dev_attr);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700780 if (rc) {
781 dev_err(&pdev->dev, "device_create_file failed\n");
782 return rc;
783 }
784 }
785
Stephen Boydaeaf2ad2012-07-03 14:33:25 -0700786 return 0;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700787}
788
789static int __devinit epm_adc_spi_probe(struct spi_device *spi)
790
791{
792 if (!epm_adc_drv)
793 return -ENODEV;
794 epm_adc_drv->epm_spi_client = spi;
795 epm_adc_drv->epm_spi_client->bits_per_word =
796 EPM_ADC_ADS_SPI_BITS_PER_WORD;
797
798 return 0;
799}
800
801static int __devexit epm_adc_spi_remove(struct spi_device *spi)
802{
803 epm_adc_drv->epm_spi_client = NULL;
804 return 0;
805}
806
807static struct spi_driver epm_spi_driver = {
808 .probe = epm_adc_spi_probe,
809 .remove = __devexit_p(epm_adc_spi_remove),
810 .driver = {
811 .name = EPM_ADC_DRIVER_NAME,
812 .owner = THIS_MODULE,
813 },
814};
815
Stephen Boyd58701e82012-04-25 11:48:28 -0700816static int __devinit epm_adc_probe(struct platform_device *pdev)
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700817{
818 struct epm_adc_drv *epm_adc;
819 struct epm_adc_platform_data *pdata = pdev->dev.platform_data;
820 int rc = 0;
821
822 if (!pdata) {
823 dev_err(&pdev->dev, "no platform data?\n");
824 return -EINVAL;
825 }
826
827 epm_adc = kzalloc(sizeof(struct epm_adc_drv), GFP_KERNEL);
828 if (!epm_adc) {
829 dev_err(&pdev->dev, "Unable to allocate memory\n");
830 return -ENOMEM;
831 }
832
833 platform_set_drvdata(pdev, epm_adc);
834 epm_adc_drv = epm_adc;
835 epm_adc->pdev = pdev;
836
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -0700837 epm_adc->misc.name = EPM_ADC_DRIVER_NAME;
838 epm_adc->misc.minor = MISC_DYNAMIC_MINOR;
839 epm_adc->misc.fops = &epm_adc_fops;
840
841 if (misc_register(&epm_adc->misc)) {
842 dev_err(&pdev->dev, "Unable to register misc device!\n");
843 return -EFAULT;
844 }
845
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700846 rc = epm_adc_init_hwmon(pdev, epm_adc);
847 if (rc) {
848 dev_err(&pdev->dev, "msm_adc_dev_init failed\n");
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -0700849 misc_deregister(&epm_adc->misc);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700850 return rc;
851 }
852
853 epm_adc->hwmon = hwmon_device_register(&pdev->dev);
854 if (IS_ERR(epm_adc->hwmon)) {
855 dev_err(&pdev->dev, "hwmon_device_register failed\n");
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -0700856 misc_deregister(&epm_adc->misc);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700857 rc = PTR_ERR(epm_adc->hwmon);
858 return rc;
859 }
860
861 mutex_init(&epm_adc->conv_lock);
862 epm_i2c_info = &pdata->epm_i2c_board_info;
863 epm_adc->bus_id = pdata->bus_id;
864 epm_gpio_expander_base_addr = pdata->gpio_expander_base_addr;
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -0700865 epm_adc_expander_register = false;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700866 return rc;
867}
868
869static int __devexit epm_adc_remove(struct platform_device *pdev)
870{
871 struct epm_adc_drv *epm_adc = platform_get_drvdata(pdev);
872 struct epm_adc_platform_data *pdata = pdev->dev.platform_data;
873 int num_chans = pdata->num_channels;
874 int i = 0;
875
Stephen Boydaeaf2ad2012-07-03 14:33:25 -0700876 for (i = 0; i < num_chans; i++)
877 device_remove_file(&pdev->dev, &epm_adc_in_attrs[i].dev_attr);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700878 hwmon_device_unregister(epm_adc->hwmon);
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -0700879 misc_deregister(&epm_adc->misc);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700880 epm_adc = NULL;
881
882 return 0;
883}
884
885static struct platform_driver epm_adc_driver = {
886 .probe = epm_adc_probe,
887 .remove = __devexit_p(epm_adc_remove),
888 .driver = {
889 .name = EPM_ADC_DRIVER_NAME,
890 .owner = THIS_MODULE,
891 },
892};
893
894static int __init epm_adc_init(void)
895{
896 int ret = 0;
897
898 ret = platform_driver_register(&epm_adc_driver);
899 if (ret) {
900 pr_err("%s: driver register failed, rc=%d\n", __func__, ret);
901 return ret;
902 }
903
904 ret = spi_register_driver(&epm_spi_driver);
905 if (ret)
906 pr_err("%s: spi register failed: rc=%d\n", __func__, ret);
907
908 return ret;
909}
910
911static void __exit epm_adc_exit(void)
912{
913 spi_unregister_driver(&epm_spi_driver);
914 platform_driver_unregister(&epm_adc_driver);
915}
916
917module_init(epm_adc_init);
918module_exit(epm_adc_exit);
919
920MODULE_DESCRIPTION("EPM ADC Driver");
921MODULE_ALIAS("platform:epm_adc");
922MODULE_LICENSE("GPL v2");