blob: a526f24015ea0523a401cb01e030ff900e84f3d5 [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
Siddartha Mohanadossefddea42012-09-04 08:23:43 -070070/* PSoc Commands */
71#define EPM_PSOC_INIT_CMD 0x1
72#define EPM_PSOC_INIT_RESPONSE_CMD 0x2
73#define EPM_PSOC_CHANNEL_ENABLE_DISABLE_CMD 0x5
74#define EPM_PSOC_CHANNEL_ENABLE_DISABLE_RESPONSE_CMD 0x6
75#define EPM_PSOC_SET_AVERAGING_CMD 0x7
76#define EPM_PSOC_SET_AVERAGING_RESPONSE_CMD 0x8
77#define EPM_PSOC_GET_LAST_MEASUREMENT_CMD 0x9
78#define EPM_PSOC_GET_LAST_MEASUREMENT_RESPONSE_CMD 0xa
79#define EPM_PSOC_GET_BUFFERED_DATA_CMD 0xb
80#define EPM_PSOC_GET_BUFFERED_RESPONSE_CMD 0xc
81#define EPM_PSOC_GET_SYSTEM_TIMESTAMP_CMD 0x11
82#define EPM_PSOC_GET_SYSTEM_TIMESTAMP_RESPONSE_CMD 0x12
83#define EPM_PSOC_SET_SYSTEM_TIMESTAMP_CMD 0x13
84#define EPM_PSOC_SET_SYSTEM_TIMESTAMP_RESPONSE_CMD 0x14
85#define EPM_PSOC_SET_CHANNEL_TYPE_CMD 0x15
86#define EPM_PSOC_SET_CHANNEL_TYPE_RESPONSE_CMD 0x16
87#define EPM_PSOC_GET_AVERAGED_DATA_CMD 0x19
88#define EPM_PSOC_GET_AVERAGED_DATA_RESPONSE_CMD 0x1a
89#define EPM_PSOC_SET_CHANNEL_SWITCH_DELAY_CMD 0x1b
90#define EPM_PSOC_SET_CHANNEL_SWITCH_DELAY_RESPONSE_CMD 0x1c
91#define EPM_PSOC_CLEAR_BUFFER_CMD 0x1d
92#define EPM_PSOC_CLEAR_BUFFER_RESPONSE_CMD 0x1e
93#define EPM_PSOC_SET_VADC_REFERENCE_CMD 0x1f
94#define EPM_PSOC_SET_VADC_REFERENCE_RESPONSE_CMD 0x20
95
96#define EPM_PSOC_GLOBAL_ENABLE 81
97#define EPM_PSOC_VREF_VOLTAGE 2048
Siddartha Mohanadossae7acf82012-12-12 10:36:07 -080098#define EPM_PSOC_MAX_ADC_CODE_15_BIT 32767
99#define EPM_PSOC_MAX_ADC_CODE_12_BIT 4096
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700100#define EPM_GLOBAL_ENABLE_MIN_DELAY 5000
101#define EPM_GLOBAL_ENABLE_MAX_DELAY 5100
102
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700103#define EPM_AVG_BUF_MASK1 0xfff00000
104#define EPM_AVG_BUF_MASK2 0xfff00
105#define EPM_AVG_BUF_MASK3 0xff
106#define EPM_AVG_BUF_MASK4 0xf0000000
107#define EPM_AVG_BUF_MASK5 0xfff0000
108#define EPM_AVG_BUF_MASK6 0xfff0
109#define EPM_AVG_BUF_MASK7 0xf
110#define EPM_AVG_BUF_MASK8 0xff000000
111#define EPM_AVG_BUF_MASK9 0xfff000
112#define EPM_AVG_BUF_MASK10 0xfff
113
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700114#define EPM_PSOC_BUFFERED_DATA_LENGTH 48
115#define EPM_PSOC_BUFFERED_DATA_LENGTH2 54
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700116
117struct epm_adc_drv {
118 struct platform_device *pdev;
119 struct device *hwmon;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700120 struct spi_device *epm_spi_client;
121 struct mutex conv_lock;
122 uint32_t bus_id;
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -0700123 struct miscdevice misc;
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700124 uint32_t channel_mask;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700125 struct epm_chan_properties epm_psoc_ch_prop[0];
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700126};
127
128static struct epm_adc_drv *epm_adc_drv;
129static struct i2c_board_info *epm_i2c_info;
130static bool epm_adc_first_request;
131static int epm_gpio_expander_base_addr;
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -0700132static bool epm_adc_expander_register;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700133
134#define GPIO_EPM_EXPANDER_IO0 epm_gpio_expander_base_addr
135#define GPIO_PWR_MON_ENABLE (GPIO_EPM_EXPANDER_IO0 + 1)
136#define GPIO_ADC1_PWDN_N (GPIO_PWR_MON_ENABLE + 1)
137#define GPIO_PWR_MON_RESET_N (GPIO_ADC1_PWDN_N + 1)
138#define GPIO_EPM_SPI_ADC1_CS_N (GPIO_PWR_MON_RESET_N + 1)
139#define GPIO_PWR_MON_START (GPIO_EPM_SPI_ADC1_CS_N + 1)
140#define GPIO_ADC1_DRDY_N (GPIO_PWR_MON_START + 1)
141#define GPIO_ADC2_PWDN_N (GPIO_ADC1_DRDY_N + 1)
142#define GPIO_EPM_SPI_ADC2_CS_N (GPIO_ADC2_PWDN_N + 1)
143#define GPIO_ADC2_DRDY_N (GPIO_EPM_SPI_ADC2_CS_N + 1)
144
145static int epm_adc_i2c_expander_register(void)
146{
147 int rc = 0;
148 static struct i2c_adapter *i2c_adap;
149 static struct i2c_client *epm_i2c_client;
150
151 rc = gpio_request(GPIO_EPM_GLOBAL_ENABLE, "EPM_GLOBAL_EN");
152 if (!rc) {
153 gpio_direction_output(GPIO_EPM_GLOBAL_ENABLE, 1);
154 } else {
155 pr_err("%s: Configure EPM_GLOBAL_EN Failed\n", __func__);
156 return rc;
157 }
158
159 usleep_range(EPM_ADC_CONVERSION_TIME_MIN,
160 EPM_ADC_CONVERSION_TIME_MAX);
161
162 i2c_adap = i2c_get_adapter(epm_adc_drv->bus_id);
163 if (i2c_adap == NULL) {
164 pr_err("%s: i2c_get_adapter() failed\n", __func__);
165 return -EINVAL;
166 }
167
168 usleep_range(EPM_ADC_CONVERSION_TIME_MIN,
169 EPM_ADC_CONVERSION_TIME_MAX);
170
171 epm_i2c_client = i2c_new_device(i2c_adap, epm_i2c_info);
172 if (IS_ERR(epm_i2c_client)) {
173 pr_err("Error with i2c epm device register\n");
174 return -ENODEV;
175 }
176
177 epm_adc_first_request = false;
178
179 return 0;
180}
181
182static int epm_adc_gpio_configure_expander_enable(void)
183{
184 int rc = 0;
185
186 if (epm_adc_first_request) {
187 rc = gpio_request(GPIO_EPM_GLOBAL_ENABLE, "EPM_GLOBAL_EN");
188 if (!rc) {
189 gpio_direction_output(GPIO_EPM_GLOBAL_ENABLE, 1);
190 } else {
191 pr_err("%s: Configure EPM_GLOBAL_EN Failed\n",
192 __func__);
193 return rc;
194 }
195 } else {
196 epm_adc_first_request = true;
197 }
198
199 usleep_range(EPM_ADC_CONVERSION_TIME_MIN,
200 EPM_ADC_CONVERSION_TIME_MAX);
201
202 rc = gpio_request(GPIO_PWR_MON_ENABLE, "GPIO_PWR_MON_ENABLE");
203 if (!rc) {
204 rc = gpio_direction_output(GPIO_PWR_MON_ENABLE, 1);
205 if (rc) {
206 pr_err("%s: Set GPIO_PWR_MON_ENABLE failed\n",
207 __func__);
208 return rc;
209 }
210 } else {
211 pr_err("%s: gpio_request GPIO_PWR_MON_ENABLE failed\n",
212 __func__);
213 return rc;
214 }
215
216 rc = gpio_request(GPIO_ADC1_PWDN_N, "GPIO_ADC1_PWDN_N");
217 if (!rc) {
218 rc = gpio_direction_output(GPIO_ADC1_PWDN_N, 1);
219 if (rc) {
220 pr_err("%s: Set GPIO_ADC1_PWDN_N failed\n", __func__);
221 return rc;
222 }
223 } else {
224 pr_err("%s: gpio_request GPIO_ADC1_PWDN_N failed\n", __func__);
225 return rc;
226 }
227
228 rc = gpio_request(GPIO_ADC2_PWDN_N, "GPIO_ADC2_PWDN_N");
229 if (!rc) {
230 rc = gpio_direction_output(GPIO_ADC2_PWDN_N, 1);
231 if (rc) {
232 pr_err("%s: Set GPIO_ADC2_PWDN_N failed\n",
233 __func__);
234 return rc;
235 }
236 } else {
237 pr_err("%s: gpio_request GPIO_ADC2_PWDN_N failed\n",
238 __func__);
239 return rc;
240 }
241
242 rc = gpio_request(GPIO_EPM_SPI_ADC1_CS_N, "GPIO_EPM_SPI_ADC1_CS_N");
243 if (!rc) {
244 rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 1);
245 if (rc) {
246 pr_err("%s:Set GPIO_EPM_SPI_ADC1_CS_N failed\n",
247 __func__);
248 return rc;
249 }
250 } else {
251 pr_err("%s: gpio_request GPIO_EPM_SPI_ADC1_CS_N failed\n",
252 __func__);
253 return rc;
254 }
255
256 rc = gpio_request(GPIO_EPM_SPI_ADC2_CS_N,
257 "GPIO_EPM_SPI_ADC2_CS_N");
258 if (!rc) {
259 rc = gpio_direction_output(GPIO_EPM_SPI_ADC2_CS_N, 1);
260 if (rc) {
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700261 pr_err("Set GPIO_EPM_SPI_ADC2_CS_N failed\n");
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700262 return rc;
263 }
264 } else {
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700265 pr_err("gpio_request GPIO_EPM_SPI_ADC2_CS_N failed\n");
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700266 return rc;
267 }
268
269 rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 0);
270 if (rc) {
271 pr_err("%s:Reset GPIO_EPM_SPI_ADC1_CS_N failed\n", __func__);
272 return rc;
273 }
274
275 rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 1);
276 if (rc) {
277 pr_err("%s: Set GPIO_EPM_SPI_ADC1_CS_N failed\n", __func__);
278 return rc;
279 }
280
281 rc = gpio_request(GPIO_PWR_MON_START, "GPIO_PWR_MON_START");
282 if (!rc) {
283 rc = gpio_direction_output(GPIO_PWR_MON_START, 0);
284 if (rc) {
285 pr_err("%s: Reset GPIO_PWR_MON_START failed\n",
286 __func__);
287 return rc;
288 }
289 } else {
290 pr_err("%s: gpio_request GPIO_PWR_MON_START failed\n",
291 __func__);
292 return rc;
293 }
294
295 rc = gpio_request(GPIO_PWR_MON_RESET_N, "GPIO_PWR_MON_RESET_N");
296 if (!rc) {
297 rc = gpio_direction_output(GPIO_PWR_MON_RESET_N, 0);
298 if (rc) {
299 pr_err("%s: Reset GPIO_PWR_MON_RESET_N failed\n",
300 __func__);
301 return rc;
302 }
303 } else {
304 pr_err("%s: gpio_request GPIO_PWR_MON_RESET_N failed\n",
305 __func__);
306 return rc;
307 }
308
309 rc = gpio_direction_output(GPIO_PWR_MON_RESET_N, 1);
310 if (rc) {
311 pr_err("%s: Set GPIO_PWR_MON_RESET_N failed\n", __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:Reset GPIO_EPM_SPI_ADC1_CS_N failed\n", __func__);
318 return rc;
319 }
320 return rc;
321}
322
323static int epm_adc_gpio_configure_expander_disable(void)
324{
325 int rc = 0;
326 gpio_free(GPIO_PWR_MON_ENABLE);
327 gpio_free(GPIO_ADC1_PWDN_N);
328 gpio_free(GPIO_ADC2_PWDN_N);
329 gpio_free(GPIO_EPM_SPI_ADC1_CS_N);
330 gpio_free(GPIO_EPM_SPI_ADC2_CS_N);
331 gpio_free(GPIO_PWR_MON_START);
332 gpio_free(GPIO_PWR_MON_RESET_N);
333 rc = gpio_direction_output(GPIO_EPM_GLOBAL_ENABLE, 0);
334 if (rc)
335 pr_debug("%s: Disable EPM_GLOBAL_EN Failed\n", __func__);
336 gpio_free(GPIO_EPM_GLOBAL_ENABLE);
337 return rc;
338}
339
340static int epm_adc_spi_chip_select(int32_t id)
341{
342 int rc = 0;
343 if (id == 0) {
344 rc = gpio_direction_output(GPIO_EPM_SPI_ADC2_CS_N, 1);
345 if (rc) {
346 pr_err("%s:Disable SPI_ADC2_CS failed",
347 __func__);
348 return rc;
349 }
350
351 rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 0);
352 if (rc) {
353 pr_err("%s:Enable SPI_ADC1_CS failed", __func__);
354 return rc;
355 }
356 } else if (id == 1) {
357 rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 1);
358 if (rc) {
359 pr_err("%s:Disable SPI_ADC1_CS failed", __func__);
360 return rc;
361 }
362 rc = gpio_direction_output(GPIO_EPM_SPI_ADC2_CS_N, 0);
363 if (rc) {
364 pr_err("%s:Enable SPI_ADC2_CS failed", __func__);
365 return rc;
366 }
367 } else {
368 rc = -EFAULT;
369 }
370 return rc;
371}
372
373static int epm_adc_ads_spi_write(struct epm_adc_drv *epm_adc,
374 uint8_t addr, uint8_t val)
375{
376 struct spi_message m;
377 struct spi_transfer t;
378 char tx_buf[2];
379 int rc = 0;
380
381 spi_setup(epm_adc->epm_spi_client);
382
383 memset(&t, 0, sizeof t);
384 memset(tx_buf, 0, sizeof tx_buf);
385 t.tx_buf = tx_buf;
386 spi_message_init(&m);
387 spi_message_add_tail(&t, &m);
388
389 tx_buf[0] = EPM_ADC_ADS_REG_WRITE_CMD | addr;
390 tx_buf[1] = val;
391
392 t.len = sizeof(tx_buf);
393 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
394
395 rc = spi_sync(epm_adc->epm_spi_client, &m);
396
397 return rc;
398}
399
400static int epm_adc_init_ads(struct epm_adc_drv *epm_adc)
401{
402 int rc = 0;
403
404 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_CONFIG0_REG_ADDR,
405 EPM_ADC_ADS_REG0_DEFAULT);
406 if (rc)
407 return rc;
408
409 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_CONFIG1_REG_ADDR,
410 EPM_ADC_ADS_REG1_DEFAULT);
411 if (rc)
412 return rc;
413 return rc;
414}
415
416static int epm_adc_ads_pulse_convert(struct epm_adc_drv *epm_adc)
417{
418 struct spi_message m;
419 struct spi_transfer t;
420 char tx_buf[1];
421 int rc = 0;
422
423 spi_setup(epm_adc->epm_spi_client);
424
425 memset(&t, 0, sizeof t);
426 memset(tx_buf, 0, sizeof tx_buf);
427 t.tx_buf = tx_buf;
428 spi_message_init(&m);
429 spi_message_add_tail(&t, &m);
430
431 tx_buf[0] = EPM_ADC_ADS_PULSE_CONVERT_CMD;
432 t.len = sizeof(tx_buf);
433 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
434
435 rc = spi_sync(epm_adc->epm_spi_client, &m);
436
437 return rc;
438}
439
440static int epm_adc_ads_read_data(struct epm_adc_drv *epm_adc, char *adc_data)
441{
442 struct spi_message m;
443 struct spi_transfer t;
444 char tx_buf[4], rx_buf[4];
445 int rc = 0;
446
447 spi_setup(epm_adc->epm_spi_client);
448
449 memset(&t, 0, sizeof t);
450 memset(tx_buf, 0, sizeof tx_buf);
451 memset(rx_buf, 0, sizeof tx_buf);
452 t.tx_buf = tx_buf;
453 t.rx_buf = rx_buf;
454 spi_message_init(&m);
455 spi_message_add_tail(&t, &m);
456
457 tx_buf[0] = EPM_ADC_ADS_DATA_READ_CMD |
458 EPM_ADC_ADS_MULTIPLE_REG_ACCESS;
459
460 t.len = sizeof(tx_buf);
461 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
462
463 rc = spi_sync(epm_adc->epm_spi_client, &m);
464 if (rc)
465 return rc;
466
467 rc = spi_sync(epm_adc->epm_spi_client, &m);
468 if (rc)
469 return rc;
470
471 rc = spi_sync(epm_adc->epm_spi_client, &m);
472 if (rc)
473 return rc;
474
475 adc_data[0] = rx_buf[1];
476 adc_data[1] = rx_buf[2];
477 adc_data[2] = rx_buf[3];
478
479 return rc;
480}
481
482static int epm_adc_hw_init(struct epm_adc_drv *epm_adc)
483{
484 int rc = 0;
485
486 mutex_lock(&epm_adc->conv_lock);
487 rc = epm_adc_gpio_configure_expander_enable();
488 if (rc != 0) {
489 pr_err("epm gpio configure expander failed, rc = %d\n", rc);
490 goto epm_adc_hw_init_err;
491 }
492 rc = epm_adc_init_ads(epm_adc);
493 if (rc) {
494 pr_err("epm_adc_init_ads failed, rc=%d\n", rc);
495 goto epm_adc_hw_init_err;
496 }
497
498epm_adc_hw_init_err:
499 mutex_unlock(&epm_adc->conv_lock);
500 return rc;
501}
502
503static int epm_adc_hw_deinit(struct epm_adc_drv *epm_adc)
504{
505 int rc = 0;
506
507 mutex_lock(&epm_adc->conv_lock);
508 rc = epm_adc_gpio_configure_expander_disable();
509 if (rc != 0) {
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700510 pr_err("gpio expander disable failed with %d\n", rc);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700511 goto epm_adc_hw_deinit_err;
512 }
513
514epm_adc_hw_deinit_err:
515 mutex_unlock(&epm_adc->conv_lock);
516 return rc;
517}
518
519static int epm_adc_ads_scale_result(struct epm_adc_drv *epm_adc,
520 uint8_t *adc_raw_data, struct epm_chan_request *conv)
521{
522 uint32_t channel_num;
523 int16_t sign_bit;
524 struct epm_adc_platform_data *pdata = epm_adc->pdev->dev.platform_data;
525 uint32_t chan_idx = (conv->device_idx * pdata->chan_per_adc) +
526 conv->channel_idx;
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700527 int64_t adc_scaled_data = 0;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700528
529 /* Get the channel number */
530 channel_num = (adc_raw_data[0] & EPM_ADC_ADS_CHANNEL_DATA_CHID);
531 sign_bit = 1;
532 /* This is the 16-bit raw data */
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700533 adc_scaled_data = ((adc_raw_data[1] << 8) | adc_raw_data[2]);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700534 /* Obtain the internal system reading */
535 if (channel_num == EPM_ADC_ADS_CHANNEL_VCC) {
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700536 adc_scaled_data *= EPM_ADC_SCALE_MILLI;
537 do_div(adc_scaled_data, EPM_ADC_SCALE_CODE_VOLTS);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700538 } else if (channel_num == EPM_ADC_ADS_CHANNEL_GAIN) {
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700539 do_div(adc_scaled_data, EPM_ADC_SCALE_CODE_GAIN);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700540 } else if (channel_num == EPM_ADC_ADS_CHANNEL_REF) {
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700541 adc_scaled_data *= EPM_ADC_SCALE_MILLI;
542 do_div(adc_scaled_data, EPM_ADC_SCALE_CODE_VOLTS);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700543 } else if (channel_num == EPM_ADC_ADS_CHANNEL_TEMP) {
544 /* Convert Code to micro-volts */
545 /* Use this formula to get the temperature reading */
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700546 adc_scaled_data -= EPM_ADC_TEMP_TO_DEGC_COEFF;
547 do_div(adc_scaled_data, EPM_ADC_TEMP_SENSOR_COEFF);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700548 } else if (channel_num == EPM_ADC_ADS_CHANNEL_OFFSET) {
549 /* The offset should be zero */
550 pr_debug("%s: ADC Channel Offset\n", __func__);
551 return -EFAULT;
552 } else {
553 channel_num -= EPM_ADC_CHANNEL_AIN_OFFSET;
554 /*
555 * Conversion for the adc channels.
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700556 * mvVRef is in milli-volts and resistorvalue is in micro-ohms.
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700557 * Hence, I = V/R gives us current in kilo-amps.
558 */
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700559 if (adc_scaled_data & EPM_ADC_MAX_NEGATIVE_SCALE_CODE) {
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700560 sign_bit = -1;
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700561 adc_scaled_data = (~adc_scaled_data
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700562 & EPM_ADC_NEG_LSB_CODE);
563 }
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700564 if (adc_scaled_data != 0) {
565 adc_scaled_data *= EPM_ADC_SCALE_FACTOR;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700566 /* Device is calibrated for 1LSB = VREF/7800h.*/
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700567 adc_scaled_data *= EPM_ADC_MILLI_VOLTS_SOURCE;
568 do_div(adc_scaled_data, EPM_ADC_VREF_CODE);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700569 /* Data will now be in micro-volts.*/
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700570 adc_scaled_data *= EPM_ADC_SCALE_MILLI;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700571 /* Divide by amplifier gain value.*/
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700572 do_div(adc_scaled_data, pdata->channel[chan_idx].gain);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700573 /* Data will now be in nano-volts.*/
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700574 do_div(adc_scaled_data, EPM_ADC_SCALE_FACTOR);
575 adc_scaled_data *= EPM_ADC_SCALE_MILLI;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700576 /* Data is now in micro-amps.*/
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700577 do_div(adc_scaled_data,
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700578 pdata->channel[chan_idx].resistorvalue);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700579 /* Set the sign bit for lekage current. */
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700580 adc_scaled_data *= sign_bit;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700581 }
582 }
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700583
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -0700584 conv->physical = (int32_t) adc_scaled_data;
Yan Hef6adab72012-08-31 11:09:36 -0700585
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700586 return 0;
587}
588
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700589static int epm_psoc_scale_result(uint32_t result, uint32_t index)
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700590{
591 struct epm_adc_drv *epm_adc = epm_adc_drv;
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700592 int32_t result_cur;
593
Siddartha Mohanadossae7acf82012-12-12 10:36:07 -0800594 if ((1 << index) & epm_adc->channel_mask) {
595 /* result = (2.048V * code)/(4096 * gain * rsense) */
596 result_cur = ((EPM_PSOC_VREF_VOLTAGE * result)/
597 EPM_PSOC_MAX_ADC_CODE_12_BIT);
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700598
Siddartha Mohanadossae7acf82012-12-12 10:36:07 -0800599 result_cur = (result_cur/
600 (epm_adc->epm_psoc_ch_prop[index].gain *
601 epm_adc->epm_psoc_ch_prop[index].resistorvalue));
602 } else {
603 /* result = (2.048V * code)/(32767 * gain * rsense) */
604 result_cur = (((EPM_PSOC_VREF_VOLTAGE * result)/
605 EPM_PSOC_MAX_ADC_CODE_15_BIT) * 1000);
606
607 result_cur = (result_cur/
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700608 (epm_adc->epm_psoc_ch_prop[index].gain *
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700609 epm_adc->epm_psoc_ch_prop[index].resistorvalue));
Siddartha Mohanadossae7acf82012-12-12 10:36:07 -0800610 }
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700611
612 return result_cur;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700613}
614
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700615static int epm_adc_blocking_conversion(struct epm_adc_drv *epm_adc,
616 struct epm_chan_request *conv)
617{
618 struct epm_adc_platform_data *pdata = epm_adc->pdev->dev.platform_data;
619 int32_t channel_num = 0, mux_chan_idx = 0;
620 char adc_data[3];
621 int rc = 0;
622
623 mutex_lock(&epm_adc->conv_lock);
624
625 rc = epm_adc_spi_chip_select(conv->device_idx);
626 if (rc) {
627 pr_err("epm_adc_chip_select failed, rc=%d\n", rc);
628 goto conv_err;
629 }
630
631 if (conv->channel_idx < pdata->chan_per_mux) {
632 /* Reset MUXSG1_REGISTER */
633 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_MUXSG1_REG_ADDR,
634 0x0);
635 if (rc)
636 goto conv_err;
637
638 mux_chan_idx = 1 << conv->channel_idx;
639 /* Select Channel index in MUXSG0_REGISTER */
640 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_MUXSG0_REG_ADDR,
641 mux_chan_idx);
642 if (rc)
643 goto conv_err;
644 } else {
645 /* Reset MUXSG0_REGISTER */
646 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_MUXSG0_REG_ADDR,
647 0x0);
648 if (rc)
649 goto conv_err;
650
651 mux_chan_idx = 1 << (conv->channel_idx - pdata->chan_per_mux);
652 /* Select Channel index in MUXSG1_REGISTER */
653 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_MUXSG1_REG_ADDR,
654 mux_chan_idx);
655 if (rc)
656 goto conv_err;
657 }
658
659 rc = epm_adc_ads_pulse_convert(epm_adc);
660 if (rc) {
661 pr_err("epm_adc_ads_pulse_convert failed, rc=%d\n", rc);
662 goto conv_err;
663 }
664
665 rc = epm_adc_ads_read_data(epm_adc, adc_data);
666 if (rc) {
667 pr_err("epm_adc_ads_read_data failed, rc=%d\n", rc);
668 goto conv_err;
669 }
670
671 channel_num = (adc_data[0] & EPM_ADC_ADS_CHANNEL_DATA_CHID);
672 pr_debug("ADC data Read: adc_data =%d, %d, %d\n",
673 adc_data[0], adc_data[1], adc_data[2]);
674
675 epm_adc_ads_scale_result(epm_adc, (uint8_t *)adc_data, conv);
676
677 pr_debug("channel_num(0x) = %x, scaled_data = %d\n",
678 (channel_num - EPM_ADC_ADS_SPI_BITS_PER_WORD),
679 conv->physical);
680conv_err:
681 mutex_unlock(&epm_adc->conv_lock);
682 return rc;
683}
684
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700685static int epm_adc_psoc_gpio_init(bool enable)
686{
687 int rc = 0;
688
689 if (enable) {
690 rc = gpio_request(EPM_PSOC_GLOBAL_ENABLE, "EPM_PSOC_GLOBAL_EN");
691 if (!rc) {
692 gpio_direction_output(EPM_PSOC_GLOBAL_ENABLE, 1);
693 } else {
694 pr_err("%s: Configure EPM_GLOBAL_EN Failed\n",
695 __func__);
696 return rc;
697 }
698 } else {
699 gpio_direction_output(EPM_PSOC_GLOBAL_ENABLE, 0);
700 gpio_free(EPM_PSOC_GLOBAL_ENABLE);
701 }
702
703 return 0;
704}
705
706static int epm_psoc_init(struct epm_adc_drv *epm_adc,
707 struct epm_psoc_init_resp *init_resp)
708{
709 struct spi_message m;
710 struct spi_transfer t;
711 char tx_buf[17], rx_buf[17];
712 int rc = 0;
713
714 spi_setup(epm_adc->epm_spi_client);
715
716 memset(&t, 0, sizeof t);
717 memset(tx_buf, 0, sizeof tx_buf);
718 memset(rx_buf, 0, sizeof tx_buf);
719 t.tx_buf = tx_buf;
720 t.rx_buf = rx_buf;
721 spi_message_init(&m);
722 spi_message_add_tail(&t, &m);
723
724 tx_buf[0] = init_resp->cmd;
725
726 t.len = sizeof(tx_buf);
727 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
728
729 rc = spi_sync(epm_adc->epm_spi_client, &m);
730 if (rc)
731 return rc;
732
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700733 rc = spi_sync(epm_adc->epm_spi_client, &m);
734 if (rc)
735 return rc;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700736 init_resp->cmd = rx_buf[0];
737 init_resp->version = rx_buf[1];
738 init_resp->compatible_ver = rx_buf[2];
739 init_resp->firm_ver[0] = rx_buf[3];
740 init_resp->firm_ver[1] = rx_buf[4];
741 init_resp->firm_ver[2] = rx_buf[5];
742 init_resp->num_dev = rx_buf[6];
743 init_resp->num_channel = rx_buf[7];
744
745 return rc;
746}
747
748static int epm_psoc_channel_configure(struct epm_adc_drv *epm_adc,
749 struct epm_psoc_channel_configure *psoc_chan_configure)
750{
751 struct spi_message m;
752 struct spi_transfer t;
753 char tx_buf[9], rx_buf[9];
754 int32_t rc = 0, chan_num;
755
756 spi_setup(epm_adc->epm_spi_client);
757
758 memset(&t, 0, sizeof t);
759 memset(tx_buf, 0, sizeof tx_buf);
760 memset(rx_buf, 0, sizeof tx_buf);
761 t.tx_buf = tx_buf;
762 t.rx_buf = rx_buf;
763 spi_message_init(&m);
764 spi_message_add_tail(&t, &m);
765
766 chan_num = psoc_chan_configure->channel_num;
767
768 tx_buf[0] = psoc_chan_configure->cmd;
769 tx_buf[1] = 0;
770 tx_buf[2] = (chan_num & 0xff000000) >> 24;
771 tx_buf[3] = (chan_num & 0xff0000) >> 16;
772 tx_buf[4] = (chan_num & 0xff00) >> 8;
773 tx_buf[5] = (chan_num & 0xff);
774
775 t.len = sizeof(tx_buf);
776 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
777
778 rc = spi_sync(epm_adc->epm_spi_client, &m);
779 if (rc)
780 return rc;
781
782 rc = spi_sync(epm_adc->epm_spi_client, &m);
783 if (rc)
784 return rc;
785
786 psoc_chan_configure->cmd = rx_buf[0];
787 psoc_chan_configure->device_num = rx_buf[1];
788 chan_num = rx_buf[2] << 24 | (rx_buf[3] << 16) | (rx_buf[4] << 8) |
789 rx_buf[5];
790 psoc_chan_configure->channel_num = chan_num;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700791
792 return rc;
793}
794
795static int epm_psoc_set_averaging(struct epm_adc_drv *epm_adc,
796 struct epm_psoc_set_avg *psoc_set_avg)
797{
798 struct spi_message m;
799 struct spi_transfer t;
800 char tx_buf[4], rx_buf[4];
801 int rc = 0;
802
803 spi_setup(epm_adc->epm_spi_client);
804
805 memset(&t, 0, sizeof t);
806 memset(tx_buf, 0, sizeof tx_buf);
807 memset(rx_buf, 0, sizeof tx_buf);
808 t.tx_buf = tx_buf;
809 t.rx_buf = rx_buf;
810 spi_message_init(&m);
811 spi_message_add_tail(&t, &m);
812
813 tx_buf[0] = psoc_set_avg->cmd;
814 tx_buf[1] = psoc_set_avg->avg_period;
815
816 t.len = sizeof(tx_buf);
817 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
818
819 rc = spi_sync(epm_adc->epm_spi_client, &m);
820 if (rc)
821 return rc;
822
823 rc = spi_sync(epm_adc->epm_spi_client, &m);
824 if (rc)
825 return rc;
826
827 psoc_set_avg->cmd = rx_buf[0];
828 psoc_set_avg->return_code = rx_buf[1];
829
830 return rc;
831}
832
833static int epm_psoc_get_data(struct epm_adc_drv *epm_adc,
834 struct epm_psoc_get_data *psoc_get_meas)
835{
836 struct spi_message m;
837 struct spi_transfer t;
838 char tx_buf[10], rx_buf[10];
839 int rc = 0;
840
841 spi_setup(epm_adc->epm_spi_client);
842
843 memset(&t, 0, sizeof t);
844 memset(tx_buf, 0, sizeof tx_buf);
845 memset(rx_buf, 0, sizeof tx_buf);
846 t.tx_buf = tx_buf;
847 t.rx_buf = rx_buf;
848 spi_message_init(&m);
849 spi_message_add_tail(&t, &m);
850
851 tx_buf[0] = psoc_get_meas->cmd;
852 tx_buf[1] = psoc_get_meas->dev_num;
853 tx_buf[2] = psoc_get_meas->chan_num;
854
855 t.len = sizeof(tx_buf);
856 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
857
858 rc = spi_sync(epm_adc->epm_spi_client, &m);
859 if (rc)
860 return rc;
861
862 rc = spi_sync(epm_adc->epm_spi_client, &m);
863 if (rc)
864 return rc;
865
866 psoc_get_meas->cmd = rx_buf[0];
867 psoc_get_meas->dev_num = rx_buf[1];
868 psoc_get_meas->chan_num = rx_buf[2];
869 psoc_get_meas->timestamp_resp_value = (rx_buf[3] << 24) |
870 (rx_buf[4] << 16) | (rx_buf[5] << 8) |
871 rx_buf[6];
872 psoc_get_meas->reading_value = (rx_buf[7] << 8) | rx_buf[8];
873
874 pr_debug("dev_num:%d, chan_num:%d\n", rx_buf[1], rx_buf[2]);
875 pr_debug("data %d\n", psoc_get_meas->reading_value);
876 return rc;
877}
878
879static int epm_psoc_get_buffered_data(struct epm_adc_drv *epm_adc,
880 struct epm_psoc_get_buffered_data *psoc_get_meas)
881{
882 struct spi_message m;
883 struct spi_transfer t;
884 char tx_buf[64], rx_buf[64];
885 int rc = 0, i;
886
887 spi_setup(epm_adc->epm_spi_client);
888
889 memset(&t, 0, sizeof t);
890 memset(tx_buf, 0, sizeof tx_buf);
891 memset(rx_buf, 0, sizeof tx_buf);
892 t.tx_buf = tx_buf;
893 t.rx_buf = rx_buf;
894 spi_message_init(&m);
895 spi_message_add_tail(&t, &m);
896
897 tx_buf[0] = psoc_get_meas->cmd;
898
899 t.len = sizeof(tx_buf);
900 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
901
902 rc = spi_sync(epm_adc->epm_spi_client, &m);
903 if (rc)
904 return rc;
905
906 rc = spi_sync(epm_adc->epm_spi_client, &m);
907 if (rc)
908 return rc;
909
910 psoc_get_meas->cmd = rx_buf[0];
911 psoc_get_meas->dev_num = rx_buf[1];
912 psoc_get_meas->status_mask = rx_buf[2];
913 psoc_get_meas->chan_idx = rx_buf[3];
914 psoc_get_meas->chan_mask = (rx_buf[4] << 24 |
915 rx_buf[5] << 16 | rx_buf[6] << 8
916 | rx_buf[7]);
917 psoc_get_meas->timestamp_start = (rx_buf[8] << 24 |
918 rx_buf[9] << 16 | rx_buf[10] << 8
919 | rx_buf[11]);
920 psoc_get_meas->timestamp_end = (rx_buf[12] << 24 |
921 rx_buf[13] << 16 | rx_buf[14] << 8
922 | rx_buf[15]);
923
924 for (i = 0; i < EPM_PSOC_BUFFERED_DATA_LENGTH; i++)
925 psoc_get_meas->buff_data[i] = rx_buf[16 + i];
926
927 return rc;
928}
929
930static int epm_psoc_timestamp(struct epm_adc_drv *epm_adc,
931 struct epm_psoc_system_time_stamp *psoc_timestamp)
932{
933 struct spi_message m;
934 struct spi_transfer t;
935 char tx_buf[10], rx_buf[10];
936 int rc = 0;
937
938 spi_setup(epm_adc->epm_spi_client);
939
940 memset(&t, 0, sizeof t);
941 memset(tx_buf, 0, sizeof tx_buf);
942 memset(rx_buf, 0, sizeof tx_buf);
943 t.tx_buf = tx_buf;
944 t.rx_buf = rx_buf;
945 spi_message_init(&m);
946 spi_message_add_tail(&t, &m);
947
948 if (psoc_timestamp->cmd == EPM_PSOC_SET_SYSTEM_TIMESTAMP_CMD) {
949 tx_buf[0] = psoc_timestamp->cmd;
950 tx_buf[1] = (psoc_timestamp->timestamp & 0xff000000) >> 24;
951 tx_buf[2] = (psoc_timestamp->timestamp & 0xff0000) >> 16;
952 tx_buf[3] = (psoc_timestamp->timestamp & 0xff00) >> 8;
953 tx_buf[4] = (psoc_timestamp->timestamp & 0xff);
954 } else if (psoc_timestamp->cmd == EPM_PSOC_GET_SYSTEM_TIMESTAMP_CMD) {
955 tx_buf[0] = psoc_timestamp->cmd;
956 }
957
958 t.len = sizeof(tx_buf);
959 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
960
961 rc = spi_sync(epm_adc->epm_spi_client, &m);
962 if (rc)
963 return rc;
964
965 rc = spi_sync(epm_adc->epm_spi_client, &m);
966 if (rc)
967 return rc;
968
969 psoc_timestamp->cmd = rx_buf[0];
970 psoc_timestamp->timestamp = rx_buf[1] << 24 | rx_buf[2] << 16 |
971 rx_buf[3] << 8 | rx_buf[4];
972
973 return rc;
974}
975
976static int epm_psoc_get_avg_buffered_switch_data(struct epm_adc_drv *epm_adc,
977 struct epm_psoc_get_avg_buffered_switch_data *psoc_get_meas)
978{
979 struct spi_message m;
980 struct spi_transfer t;
981 char tx_buf[64], rx_buf[64];
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700982 int rc = 0, i = 0, j = 0, z = 0;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700983
984 spi_setup(epm_adc->epm_spi_client);
985
986 memset(&t, 0, sizeof t);
987 memset(tx_buf, 0, sizeof tx_buf);
988 memset(rx_buf, 0, sizeof tx_buf);
989 t.tx_buf = tx_buf;
990 t.rx_buf = rx_buf;
991 spi_message_init(&m);
992 spi_message_add_tail(&t, &m);
993
994 tx_buf[0] = psoc_get_meas->cmd;
995
996 t.len = sizeof(tx_buf);
997 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
998
999 rc = spi_sync(epm_adc->epm_spi_client, &m);
1000 if (rc)
1001 return rc;
1002
1003 rc = spi_sync(epm_adc->epm_spi_client, &m);
1004 if (rc)
1005 return rc;
1006
1007 psoc_get_meas->cmd = rx_buf[0];
1008 psoc_get_meas->status = rx_buf[1];
1009 psoc_get_meas->timestamp_start = (rx_buf[2] << 24 |
1010 rx_buf[3] << 16 | rx_buf[4] << 8
1011 | rx_buf[5]);
1012 psoc_get_meas->channel_mask = (rx_buf[6] << 24 |
1013 rx_buf[7] << 16 | rx_buf[8] << 8
1014 | rx_buf[9]);
1015
1016 for (i = 0; i < EPM_PSOC_BUFFERED_DATA_LENGTH2; i++)
1017 psoc_get_meas->avg_data[i] = rx_buf[10 + i];
1018
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001019 i = j = 0;
1020 for (z = 0; z < 4; z++) {
1021 psoc_get_meas->data[i].channel = i;
1022 psoc_get_meas->data[i].avg_buffer_sample =
1023 rx_buf[10 + j] & EPM_AVG_BUF_MASK1;
1024 i++;
1025 j++;
1026 psoc_get_meas->data[i].avg_buffer_sample =
1027 rx_buf[10 + j] & EPM_AVG_BUF_MASK2;
1028 i++;
1029 j++;
1030 psoc_get_meas->data[i].avg_buffer_sample =
1031 rx_buf[10 + j] & EPM_AVG_BUF_MASK3;
1032 psoc_get_meas->data[i].avg_buffer_sample <<= 8;
1033 j++;
1034 psoc_get_meas->data[i].avg_buffer_sample =
1035 psoc_get_meas->data[i].avg_buffer_sample |
1036 (rx_buf[10 + j] & EPM_AVG_BUF_MASK4);
1037 i++;
1038 j++;
1039 psoc_get_meas->data[i].avg_buffer_sample =
1040 rx_buf[10 + j] & EPM_AVG_BUF_MASK5;
1041 i++;
1042 j++;
1043 psoc_get_meas->data[i].avg_buffer_sample =
1044 rx_buf[10 + j] & EPM_AVG_BUF_MASK6;
1045 i++;
1046 j++;
1047 psoc_get_meas->data[i].avg_buffer_sample =
1048 rx_buf[10 + j] & EPM_AVG_BUF_MASK7;
1049 psoc_get_meas->data[i].avg_buffer_sample <<= 4;
1050 j++;
1051 psoc_get_meas->data[i].avg_buffer_sample =
1052 psoc_get_meas->data[i].avg_buffer_sample |
1053 (rx_buf[10 + j] & EPM_AVG_BUF_MASK8);
1054 i++;
1055 j++;
1056 psoc_get_meas->data[i].avg_buffer_sample =
1057 rx_buf[10 + j] & EPM_AVG_BUF_MASK9;
1058 i++;
1059 j++;
1060 psoc_get_meas->data[i].avg_buffer_sample =
1061 rx_buf[10 + j] & EPM_AVG_BUF_MASK10;
1062 }
1063
1064 for (z = 0; z < 32; z++) {
1065 if (psoc_get_meas->data[z].avg_buffer_sample != 0)
1066 psoc_get_meas->data[z].result = epm_psoc_scale_result(
1067 psoc_get_meas->data[z].avg_buffer_sample, z);
1068 }
1069
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001070 return rc;
1071}
1072
1073static int epm_psoc_set_vadc(struct epm_adc_drv *epm_adc,
1074 struct epm_psoc_set_vadc *psoc_set_vadc)
1075{
1076 struct spi_message m;
1077 struct spi_transfer t;
1078 char tx_buf[10], rx_buf[10];
1079 int rc = 0;
1080
1081 spi_setup(epm_adc->epm_spi_client);
1082
1083 memset(&t, 0, sizeof t);
1084 memset(tx_buf, 0, sizeof tx_buf);
1085 memset(rx_buf, 0, sizeof tx_buf);
1086 t.tx_buf = tx_buf;
1087 t.rx_buf = rx_buf;
1088 spi_message_init(&m);
1089 spi_message_add_tail(&t, &m);
1090
1091 tx_buf[0] = psoc_set_vadc->cmd;
1092 tx_buf[1] = psoc_set_vadc->vadc_dev;
1093 tx_buf[2] = (psoc_set_vadc->vadc_voltage & 0xff000000) >> 24;
1094 tx_buf[3] = (psoc_set_vadc->vadc_voltage & 0xff0000) >> 16;
1095 tx_buf[4] = (psoc_set_vadc->vadc_voltage & 0xff00) >> 8;
1096 tx_buf[5] = psoc_set_vadc->vadc_voltage & 0xff;
1097
1098 t.len = sizeof(tx_buf);
1099 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
1100
1101 rc = spi_sync(epm_adc->epm_spi_client, &m);
1102 if (rc)
1103 return rc;
1104
1105 rc = spi_sync(epm_adc->epm_spi_client, &m);
1106 if (rc)
1107 return rc;
1108
1109 psoc_set_vadc->cmd = rx_buf[0];
1110 psoc_set_vadc->vadc_dev = rx_buf[1];
1111 psoc_set_vadc->vadc_voltage = (rx_buf[2] << 24) | (rx_buf[3] << 16) |
1112 (rx_buf[4] << 8) | (rx_buf[5]);
1113
1114 return rc;
1115}
1116
1117static int epm_psoc_set_channel_switch(struct epm_adc_drv *epm_adc,
1118 struct epm_psoc_set_channel_switch *psoc_channel_switch)
1119{
1120 struct spi_message m;
1121 struct spi_transfer t;
1122 char tx_buf[10], rx_buf[10];
1123 int rc = 0;
1124
1125 spi_setup(epm_adc->epm_spi_client);
1126
1127 memset(&t, 0, sizeof t);
1128 memset(tx_buf, 0, sizeof tx_buf);
1129 memset(rx_buf, 0, sizeof tx_buf);
1130 t.tx_buf = tx_buf;
1131 t.rx_buf = rx_buf;
1132 spi_message_init(&m);
1133 spi_message_add_tail(&t, &m);
1134
1135 tx_buf[0] = psoc_channel_switch->cmd;
1136 tx_buf[1] = psoc_channel_switch->dev;
1137 tx_buf[2] = (psoc_channel_switch->delay & 0xff000000) >> 24;
1138 tx_buf[3] = (psoc_channel_switch->delay & 0xff0000) >> 16;
1139 tx_buf[4] = (psoc_channel_switch->delay & 0xff00) >> 8;
1140 tx_buf[5] = psoc_channel_switch->delay & 0xff;
1141
1142 t.len = sizeof(tx_buf);
1143 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
1144
1145 rc = spi_sync(epm_adc->epm_spi_client, &m);
1146 if (rc)
1147 return rc;
1148
1149 rc = spi_sync(epm_adc->epm_spi_client, &m);
1150 if (rc)
1151 return rc;
1152
1153 psoc_channel_switch->cmd = rx_buf[0];
1154 psoc_channel_switch->dev = rx_buf[1];
1155 psoc_channel_switch->delay = rx_buf[2] << 24 |
1156 rx_buf[3] << 16 |
1157 rx_buf[4] << 8 | rx_buf[5];
1158
1159 return rc;
1160}
1161
1162static int epm_psoc_clear_buffer(struct epm_adc_drv *epm_adc)
1163{
1164 struct spi_message m;
1165 struct spi_transfer t;
1166 char tx_buf[3], rx_buf[3];
1167 int rc = 0;
1168
1169 spi_setup(epm_adc->epm_spi_client);
1170
1171 memset(&t, 0, sizeof t);
1172 memset(tx_buf, 0, sizeof tx_buf);
1173 memset(rx_buf, 0, sizeof tx_buf);
1174 t.tx_buf = tx_buf;
1175 t.rx_buf = rx_buf;
1176 spi_message_init(&m);
1177 spi_message_add_tail(&t, &m);
1178
1179 tx_buf[0] = EPM_PSOC_CLEAR_BUFFER_CMD;
1180
1181 t.len = sizeof(tx_buf);
1182 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
1183
1184 rc = spi_sync(epm_adc->epm_spi_client, &m);
1185 if (rc)
1186 return rc;
1187
1188 rc = spi_sync(epm_adc->epm_spi_client, &m);
1189 if (rc)
1190 return rc;
1191
1192 rc = rx_buf[2];
1193
1194 return rc;
1195}
1196
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001197static long epm_adc_ioctl(struct file *file, unsigned int cmd,
1198 unsigned long arg)
1199{
1200 struct epm_adc_drv *epm_adc = epm_adc_drv;
1201
1202 switch (cmd) {
1203 case EPM_ADC_REQUEST:
1204 {
1205 struct epm_chan_request conv;
1206 int rc;
1207
1208 if (copy_from_user(&conv, (void __user *)arg,
1209 sizeof(struct epm_chan_request)))
1210 return -EFAULT;
1211
1212 rc = epm_adc_blocking_conversion(epm_adc, &conv);
1213 if (rc) {
1214 pr_err("Failed EPM conversion:%d\n", rc);
1215 return rc;
1216 }
1217
1218 if (copy_to_user((void __user *)arg, &conv,
1219 sizeof(struct epm_chan_request)))
1220 return -EFAULT;
1221 break;
1222 }
1223 case EPM_ADC_INIT:
1224 {
1225 uint32_t result;
1226 if (!epm_adc_expander_register) {
1227 result = epm_adc_i2c_expander_register();
1228 if (result) {
1229 pr_err("Failed i2c register:%d\n",
1230 result);
1231 return result;
1232 }
1233 epm_adc_expander_register = true;
1234 }
1235
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001236 result = epm_adc_hw_init(epm_adc);
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001237
1238 if (copy_to_user((void __user *)arg, &result,
1239 sizeof(uint32_t)))
1240 return -EFAULT;
1241 break;
1242 }
1243 case EPM_ADC_DEINIT:
1244 {
1245 uint32_t result;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001246 result = epm_adc_hw_deinit(epm_adc);
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001247
1248 if (copy_to_user((void __user *)arg, &result,
1249 sizeof(uint32_t)))
1250 return -EFAULT;
1251 break;
1252 }
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001253 case EPM_PSOC_ADC_INIT:
1254 {
1255 struct epm_psoc_init_resp psoc_init;
1256 int rc;
1257
1258 if (copy_from_user(&psoc_init, (void __user *)arg,
1259 sizeof(struct epm_psoc_init_resp)))
1260 return -EFAULT;
1261
1262 psoc_init.cmd = EPM_PSOC_INIT_CMD;
1263 rc = epm_psoc_init(epm_adc, &psoc_init);
1264 if (rc) {
1265 pr_err("PSOC initialization failed\n");
1266 return -EINVAL;
1267 }
1268
1269 if (copy_to_user((void __user *)arg, &psoc_init,
1270 sizeof(struct epm_psoc_init_resp)))
1271 return -EFAULT;
1272 break;
1273 }
1274 case EPM_PSOC_ADC_CHANNEL_ENABLE:
1275 case EPM_PSOC_ADC_CHANNEL_DISABLE:
1276 {
1277 struct epm_psoc_channel_configure psoc_chan_configure;
1278 int rc;
1279
1280 if (copy_from_user(&psoc_chan_configure,
1281 (void __user *)arg,
1282 sizeof(struct epm_psoc_channel_configure)))
1283 return -EFAULT;
1284
1285 psoc_chan_configure.cmd =
1286 EPM_PSOC_CHANNEL_ENABLE_DISABLE_CMD;
1287 rc = epm_psoc_channel_configure(epm_adc,
1288 &psoc_chan_configure);
1289 if (rc) {
1290 pr_err("PSOC channel configure failed\n");
1291 return -EINVAL;
1292 }
1293
1294 if (copy_to_user((void __user *)arg,
1295 &psoc_chan_configure,
1296 sizeof(struct epm_psoc_channel_configure)))
1297 return -EFAULT;
1298 break;
1299 }
1300 case EPM_PSOC_ADC_SET_AVERAGING:
1301 {
1302 struct epm_psoc_set_avg psoc_set_avg;
1303 int rc;
1304
1305 if (copy_from_user(&psoc_set_avg, (void __user *)arg,
1306 sizeof(struct epm_psoc_set_avg)))
1307 return -EFAULT;
1308
1309 psoc_set_avg.cmd = EPM_PSOC_SET_AVERAGING_CMD;
1310 rc = epm_psoc_set_averaging(epm_adc, &psoc_set_avg);
1311 if (rc) {
1312 pr_err("PSOC averaging failed\n");
1313 return -EINVAL;
1314 }
1315
1316 if (copy_to_user((void __user *)arg, &psoc_set_avg,
1317 sizeof(struct epm_psoc_set_avg)))
1318 return -EFAULT;
1319 break;
1320 }
1321 case EPM_PSOC_ADC_GET_LAST_MEASUREMENT:
1322 {
1323 struct epm_psoc_get_data psoc_get_data;
1324 int rc;
1325
1326 if (copy_from_user(&psoc_get_data,
1327 (void __user *)arg,
1328 sizeof(struct epm_psoc_get_data)))
1329 return -EFAULT;
1330
1331 psoc_get_data.cmd = EPM_PSOC_GET_LAST_MEASUREMENT_CMD;
1332 rc = epm_psoc_get_data(epm_adc, &psoc_get_data);
1333 if (rc) {
1334 pr_err("PSOC last measured data failed\n");
1335 return -EINVAL;
1336 }
1337
Siddartha Mohanadoss53c6ebe2012-12-06 14:17:30 -08001338 psoc_get_data.reading_value = epm_psoc_scale_result(
1339 psoc_get_data.reading_value,
1340 psoc_get_data.chan_num);
1341
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001342 if (copy_to_user((void __user *)arg, &psoc_get_data,
1343 sizeof(struct epm_psoc_get_data)))
1344 return -EFAULT;
1345 break;
1346 }
1347 case EPM_PSOC_ADC_GET_BUFFERED_DATA:
1348 {
1349 struct epm_psoc_get_buffered_data psoc_get_data;
1350 int rc;
1351
1352 if (copy_from_user(&psoc_get_data,
1353 (void __user *)arg,
1354 sizeof(struct epm_psoc_get_buffered_data)))
1355 return -EFAULT;
1356
1357 psoc_get_data.cmd = EPM_PSOC_GET_BUFFERED_DATA_CMD;
1358 rc = epm_psoc_get_buffered_data(epm_adc,
1359 &psoc_get_data);
1360 if (rc) {
1361 pr_err("PSOC buffered measurement failed\n");
1362 return -EINVAL;
1363 }
1364
1365 if (copy_to_user((void __user *)arg, &psoc_get_data,
1366 sizeof(struct epm_psoc_get_buffered_data)))
1367 return -EFAULT;
1368 break;
1369 }
1370 case EPM_PSOC_ADC_GET_SYSTEM_TIMESTAMP:
1371 case EPM_PSOC_ADC_SET_SYSTEM_TIMESTAMP:
1372 {
1373 struct epm_psoc_system_time_stamp psoc_timestamp;
1374 int rc;
1375
1376 if (copy_from_user(&psoc_timestamp,
1377 (void __user *)arg,
1378 sizeof(struct epm_psoc_system_time_stamp)))
1379 return -EFAULT;
1380
1381 rc = epm_psoc_timestamp(epm_adc, &psoc_timestamp);
1382 if (rc) {
1383 pr_err("PSOC buffered measurement failed\n");
1384 return -EINVAL;
1385 }
1386
1387 if (copy_to_user((void __user *)arg, &psoc_timestamp,
1388 sizeof(struct epm_psoc_system_time_stamp)))
1389 return -EFAULT;
1390 break;
1391 }
1392 case EPM_PSOC_ADC_GET_AVERAGE_DATA:
1393 {
1394 struct epm_psoc_get_avg_buffered_switch_data
1395 psoc_get_data;
1396 int rc;
1397
1398 if (copy_from_user(&psoc_get_data,
1399 (void __user *)arg,
1400 sizeof(struct
1401 epm_psoc_get_avg_buffered_switch_data)))
1402 return -EFAULT;
1403
1404 psoc_get_data.cmd = EPM_PSOC_GET_AVERAGED_DATA_CMD;
1405 rc = epm_psoc_get_avg_buffered_switch_data(epm_adc,
1406 &psoc_get_data);
1407 if (rc) {
1408 pr_err("Get averaged buffered data failed\n");
1409 return -EINVAL;
1410 }
1411
1412 if (copy_to_user((void __user *)arg, &psoc_get_data,
1413 sizeof(struct
1414 epm_psoc_get_avg_buffered_switch_data)))
1415 return -EFAULT;
1416 break;
1417 }
1418 case EPM_PSOC_SET_CHANNEL_SWITCH:
1419 {
1420 struct epm_psoc_set_channel_switch psoc_channel_switch;
1421 int rc;
1422
1423 if (copy_from_user(&psoc_channel_switch,
1424 (void __user *)arg,
1425 sizeof(struct epm_psoc_set_channel_switch)))
1426 return -EFAULT;
1427
1428 rc = epm_psoc_set_channel_switch(epm_adc,
1429 &psoc_channel_switch);
1430 if (rc) {
1431 pr_err("PSOC channel switch failed\n");
1432 return -EINVAL;
1433 }
1434
1435 if (copy_to_user((void __user *)arg,
1436 &psoc_channel_switch,
1437 sizeof(struct epm_psoc_set_channel_switch)))
1438 return -EFAULT;
1439 break;
1440 }
1441 case EPM_PSOC_CLEAR_BUFFER:
1442 {
1443 int rc;
1444 rc = epm_psoc_clear_buffer(epm_adc);
1445 if (rc) {
1446 pr_err("PSOC clear buffer failed\n");
1447 return -EINVAL;
1448 }
1449
1450 if (copy_to_user((void __user *)arg, &rc,
1451 sizeof(uint32_t)))
1452 return -EFAULT;
1453 break;
1454 }
1455 case EPM_PSOC_ADC_SET_VADC_REFERENCE:
1456 {
1457 struct epm_psoc_set_vadc psoc_set_vadc;
1458 int rc;
1459
1460 if (copy_from_user(&psoc_set_vadc,
1461 (void __user *)arg,
1462 sizeof(struct epm_psoc_set_vadc)))
1463 return -EFAULT;
1464
1465 rc = epm_psoc_set_vadc(epm_adc, &psoc_set_vadc);
1466 if (rc) {
1467 pr_err("PSOC set VADC failed\n");
1468 return -EINVAL;
1469 }
1470
1471 if (copy_to_user((void __user *)arg, &psoc_set_vadc,
1472 sizeof(struct epm_psoc_set_vadc)))
1473 return -EFAULT;
1474 break;
1475 }
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001476 default:
1477 return -EINVAL;
1478 }
1479
1480 return 0;
1481}
1482
1483const struct file_operations epm_adc_fops = {
1484 .unlocked_ioctl = epm_adc_ioctl,
1485};
1486
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001487static ssize_t epm_adc_psoc_show_in(struct device *dev,
1488 struct device_attribute *devattr, char *buf)
1489{
1490 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1491 struct epm_adc_drv *epm_adc = epm_adc_drv;
1492 struct epm_psoc_init_resp init_resp;
1493 struct epm_psoc_channel_configure psoc_chan_configure;
1494 struct epm_psoc_get_data psoc_get_meas;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001495 int rc = 0;
1496
1497 rc = epm_adc_psoc_gpio_init(true);
1498 if (rc) {
1499 pr_err("GPIO init failed\n");
1500 return 0;
1501 }
1502 usleep_range(EPM_GLOBAL_ENABLE_MIN_DELAY,
1503 EPM_GLOBAL_ENABLE_MAX_DELAY);
1504
1505 init_resp.cmd = EPM_PSOC_INIT_CMD;
1506 rc = epm_psoc_init(epm_adc, &init_resp);
1507 if (rc) {
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001508 pr_err("PSOC init failed %d\n", rc);
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001509 return 0;
1510 }
1511
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001512
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001513 psoc_chan_configure.channel_num = (1 << attr->index);
1514 psoc_chan_configure.cmd = EPM_PSOC_CHANNEL_ENABLE_DISABLE_CMD;
1515 rc = epm_psoc_channel_configure(epm_adc, &psoc_chan_configure);
1516 if (rc) {
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001517 pr_err("PSOC channel configure failed\n");
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001518 return 0;
1519 }
1520
1521 usleep_range(EPM_GLOBAL_ENABLE_MIN_DELAY,
1522 EPM_GLOBAL_ENABLE_MAX_DELAY);
1523
1524 psoc_get_meas.cmd = EPM_PSOC_GET_LAST_MEASUREMENT_CMD;
1525 psoc_get_meas.dev_num = 0;
1526 psoc_get_meas.chan_num = attr->index;
1527 rc = epm_psoc_get_data(epm_adc, &psoc_get_meas);
1528 if (rc) {
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001529 pr_err("PSOC get data failed\n");
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001530 return 0;
1531 }
1532
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001533 psoc_get_meas.reading_value = epm_psoc_scale_result(
1534 psoc_get_meas.reading_value,
1535 attr->index);
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001536
1537 rc = epm_adc_psoc_gpio_init(false);
1538 if (rc) {
1539 pr_err("GPIO de-init failed\n");
1540 return 0;
1541 }
1542
1543 return snprintf(buf, 16, "Result: %d\n", psoc_get_meas.reading_value);
1544}
1545
1546static struct sensor_device_attribute epm_adc_psoc_in_attrs[] = {
Siddartha Mohanadoss37e1c372012-12-06 14:19:11 -08001547 SENSOR_ATTR(psoc0_chan0, S_IRUGO, epm_adc_psoc_show_in, NULL, 0),
1548 SENSOR_ATTR(psoc0_chan1, S_IRUGO, epm_adc_psoc_show_in, NULL, 1),
1549 SENSOR_ATTR(psoc0_chan2, S_IRUGO, epm_adc_psoc_show_in, NULL, 2),
1550 SENSOR_ATTR(psoc0_chan3, S_IRUGO, epm_adc_psoc_show_in, NULL, 3),
1551 SENSOR_ATTR(psoc0_chan4, S_IRUGO, epm_adc_psoc_show_in, NULL, 4),
1552 SENSOR_ATTR(psoc0_chan5, S_IRUGO, epm_adc_psoc_show_in, NULL, 5),
1553 SENSOR_ATTR(psoc0_chan6, S_IRUGO, epm_adc_psoc_show_in, NULL, 6),
1554 SENSOR_ATTR(psoc0_chan7, S_IRUGO, epm_adc_psoc_show_in, NULL, 7),
1555 SENSOR_ATTR(psoc0_chan8, S_IRUGO, epm_adc_psoc_show_in, NULL, 8),
1556 SENSOR_ATTR(psoc0_chan9, S_IRUGO, epm_adc_psoc_show_in, NULL, 9),
1557 SENSOR_ATTR(psoc0_chan10, S_IRUGO, epm_adc_psoc_show_in, NULL, 10),
1558 SENSOR_ATTR(psoc0_chan11, S_IRUGO, epm_adc_psoc_show_in, NULL, 11),
1559 SENSOR_ATTR(psoc0_chan12, S_IRUGO, epm_adc_psoc_show_in, NULL, 12),
1560 SENSOR_ATTR(psoc0_chan13, S_IRUGO, epm_adc_psoc_show_in, NULL, 13),
1561 SENSOR_ATTR(psoc0_chan14, S_IRUGO, epm_adc_psoc_show_in, NULL, 14),
1562 SENSOR_ATTR(psoc0_chan15, S_IRUGO, epm_adc_psoc_show_in, NULL, 15),
1563 SENSOR_ATTR(psoc0_chan16, S_IRUGO, epm_adc_psoc_show_in, NULL, 16),
1564 SENSOR_ATTR(psoc0_chan17, S_IRUGO, epm_adc_psoc_show_in, NULL, 17),
1565 SENSOR_ATTR(psoc0_chan18, S_IRUGO, epm_adc_psoc_show_in, NULL, 18),
1566 SENSOR_ATTR(psoc0_chan19, S_IRUGO, epm_adc_psoc_show_in, NULL, 19),
1567 SENSOR_ATTR(psoc0_chan20, S_IRUGO, epm_adc_psoc_show_in, NULL, 20),
1568 SENSOR_ATTR(psoc0_chan21, S_IRUGO, epm_adc_psoc_show_in, NULL, 21),
1569 SENSOR_ATTR(psoc0_chan22, S_IRUGO, epm_adc_psoc_show_in, NULL, 22),
1570 SENSOR_ATTR(psoc0_chan23, S_IRUGO, epm_adc_psoc_show_in, NULL, 23),
1571 SENSOR_ATTR(psoc0_chan24, S_IRUGO, epm_adc_psoc_show_in, NULL, 24),
1572 SENSOR_ATTR(psoc0_chan25, S_IRUGO, epm_adc_psoc_show_in, NULL, 25),
1573 SENSOR_ATTR(psoc0_chan26, S_IRUGO, epm_adc_psoc_show_in, NULL, 26),
1574 SENSOR_ATTR(psoc0_chan27, S_IRUGO, epm_adc_psoc_show_in, NULL, 27),
1575 SENSOR_ATTR(psoc0_chan28, S_IRUGO, epm_adc_psoc_show_in, NULL, 28),
1576 SENSOR_ATTR(psoc0_chan29, S_IRUGO, epm_adc_psoc_show_in, NULL, 29),
1577 SENSOR_ATTR(psoc0_chan30, S_IRUGO, epm_adc_psoc_show_in, NULL, 30),
1578 SENSOR_ATTR(psoc0_chan31, S_IRUGO, epm_adc_psoc_show_in, NULL, 31),
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001579};
1580
1581static int __devinit epm_adc_psoc_init_hwmon(struct spi_device *spi,
1582 struct epm_adc_drv *epm_adc)
1583{
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001584 int i, rc, num_chans = 31;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001585
1586 for (i = 0; i < num_chans; i++) {
1587 rc = device_create_file(&spi->dev,
1588 &epm_adc_psoc_in_attrs[i].dev_attr);
1589 if (rc) {
1590 dev_err(&spi->dev, "device_create_file failed\n");
1591 return rc;
1592 }
1593 }
1594
1595 return 0;
1596}
1597
1598static int get_device_tree_data(struct spi_device *spi)
1599{
1600 const struct device_node *node = spi->dev.of_node;
1601 struct epm_adc_drv *epm_adc;
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001602 u32 *epm_ch_gain, *epm_ch_rsense;
1603 u32 rc = 0, epm_num_channels, i, channel_mask;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001604
1605 if (!node)
1606 return -EINVAL;
1607
1608 rc = of_property_read_u32(node,
1609 "qcom,channels", &epm_num_channels);
1610 if (rc) {
1611 dev_err(&spi->dev, "missing channel numbers\n");
1612 return -ENODEV;
1613 }
1614
1615 epm_ch_gain = devm_kzalloc(&spi->dev,
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001616 epm_num_channels * sizeof(u32), GFP_KERNEL);
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001617 if (!epm_ch_gain) {
1618 dev_err(&spi->dev, "cannot allocate gain\n");
1619 return -ENOMEM;
1620 }
1621
1622 epm_ch_rsense = devm_kzalloc(&spi->dev,
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001623 epm_num_channels * sizeof(u32), GFP_KERNEL);
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001624 if (!epm_ch_rsense) {
1625 dev_err(&spi->dev, "cannot allocate rsense\n");
1626 return -ENOMEM;
1627 }
1628
1629 rc = of_property_read_u32_array(node,
1630 "qcom,gain", epm_ch_gain, epm_num_channels);
1631 if (rc) {
1632 dev_err(&spi->dev, "invalid gain property:%d\n", rc);
1633 return rc;
1634 }
1635
1636 rc = of_property_read_u32_array(node,
1637 "qcom,rsense", epm_ch_rsense, epm_num_channels);
1638 if (rc) {
1639 dev_err(&spi->dev, "invalid rsense property:%d\n", rc);
1640 return rc;
1641 }
1642
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001643 rc = of_property_read_u32(node,
1644 "qcom,channel-type", &channel_mask);
1645 if (rc) {
1646 dev_err(&spi->dev, "missing channel mask\n");
1647 return -ENODEV;
1648 }
1649
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001650 epm_adc = devm_kzalloc(&spi->dev,
1651 sizeof(struct epm_adc_drv) +
1652 (epm_num_channels *
1653 sizeof(struct epm_chan_properties)),
1654 GFP_KERNEL);
1655 if (!epm_adc) {
1656 dev_err(&spi->dev, "Unable to allocate memory\n");
1657 return -ENOMEM;
1658 }
1659
1660 for (i = 0; i < epm_num_channels; i++) {
1661 epm_adc->epm_psoc_ch_prop[i].resistorvalue =
1662 epm_ch_rsense[i];
1663 epm_adc->epm_psoc_ch_prop[i].gain =
1664 epm_ch_gain[i];
1665 }
1666
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001667 epm_adc->channel_mask = channel_mask;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001668 epm_adc_drv = epm_adc;
1669
1670 return 0;
1671}
1672
1673static int __devinit epm_adc_psoc_spi_probe(struct spi_device *spi)
1674{
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001675
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001676 struct epm_adc_drv *epm_adc;
1677 struct device_node *node = spi->dev.of_node;
1678 int rc = 0;
1679
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001680 if (node) {
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001681 rc = get_device_tree_data(spi);
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001682 if (rc)
1683 return rc;
1684 } else {
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -07001685 epm_adc = epm_adc_drv;
1686 epm_adc_drv->epm_spi_client = spi;
1687 epm_adc_drv->epm_spi_client->bits_per_word =
1688 EPM_ADC_ADS_SPI_BITS_PER_WORD;
1689 return rc;
1690 }
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001691
1692 epm_adc = epm_adc_drv;
1693 epm_adc->misc.name = EPM_ADC_DRIVER_NAME;
1694 epm_adc->misc.minor = MISC_DYNAMIC_MINOR;
Siddartha Mohanadoss5e8df032012-11-12 17:54:03 -08001695
1696 if (node) {
1697 epm_adc->misc.fops = &epm_adc_fops;
1698 if (misc_register(&epm_adc->misc)) {
1699 pr_err("Unable to register misc device!\n");
1700 return -EFAULT;
1701 }
1702 }
1703
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001704 epm_adc_drv->epm_spi_client = spi;
1705 epm_adc_drv->epm_spi_client->bits_per_word =
1706 EPM_ADC_ADS_SPI_BITS_PER_WORD;
1707 rc = epm_adc_psoc_init_hwmon(spi, epm_adc);
1708 if (rc) {
1709 dev_err(&spi->dev, "msm_adc_dev_init failed\n");
1710 return rc;
1711 }
1712
1713 epm_adc->hwmon = hwmon_device_register(&spi->dev);
1714 if (IS_ERR(epm_adc->hwmon)) {
1715 dev_err(&spi->dev, "hwmon_device_register failed\n");
1716 return rc;
1717 }
1718
1719 mutex_init(&epm_adc->conv_lock);
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001720 return rc;
1721}
1722
1723static int __devexit epm_adc_psoc_spi_remove(struct spi_device *spi)
1724{
1725 epm_adc_drv->epm_spi_client = NULL;
1726 return 0;
1727}
1728
1729static const struct of_device_id epm_adc_psoc_match_table[] = {
Siddartha Mohanadoss6eadd582012-10-25 15:29:22 -07001730 { .compatible = "cy,epm-adc-cy8c5568lti-114",
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001731 },
1732 {}
1733};
1734
1735static struct spi_driver epm_spi_driver = {
1736 .probe = epm_adc_psoc_spi_probe,
1737 .remove = __devexit_p(epm_adc_psoc_spi_remove),
1738 .driver = {
1739 .name = EPM_ADC_DRIVER_NAME,
1740 .of_match_table = epm_adc_psoc_match_table,
1741 },
1742};
1743
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001744static ssize_t epm_adc_show_in(struct device *dev,
1745 struct device_attribute *devattr, char *buf)
1746{
1747 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1748 struct epm_adc_drv *epm_adc = dev_get_drvdata(dev);
1749 struct epm_adc_platform_data *pdata = epm_adc->pdev->dev.platform_data;
1750 struct epm_chan_request conv;
1751 int rc = 0;
1752
1753 conv.device_idx = attr->index / pdata->chan_per_adc;
1754 conv.channel_idx = attr->index % pdata->chan_per_adc;
1755 conv.physical = 0;
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001756 pr_info("%s: device_idx=%d channel_idx=%d", __func__, conv.device_idx,
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001757 conv.channel_idx);
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001758
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001759 if (!epm_adc_expander_register) {
1760 rc = epm_adc_i2c_expander_register();
1761 if (rc) {
1762 pr_err("I2C expander register failed:%d\n", rc);
1763 return rc;
1764 }
1765 epm_adc_expander_register = true;
1766 }
1767
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001768 rc = epm_adc_hw_init(epm_adc);
1769 if (rc) {
1770 pr_err("%s: epm_adc_hw_init() failed, rc = %d",
1771 __func__, rc);
1772 return 0;
1773 }
1774
1775 rc = epm_adc_blocking_conversion(epm_adc, &conv);
1776 if (rc) {
1777 pr_err("%s: epm_adc_blocking_conversion() failed, rc = %d\n",
1778 __func__, rc);
1779 return 0;
1780 }
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001781
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001782 rc = epm_adc_hw_deinit(epm_adc);
1783 if (rc) {
1784 pr_err("%s: epm_adc_hw_deinit() failed, rc = %d",
1785 __func__, rc);
1786 return 0;
1787 }
1788
1789 return snprintf(buf, 16, "Result: %d\n", conv.physical);
1790}
1791
Stephen Boydaeaf2ad2012-07-03 14:33:25 -07001792static struct sensor_device_attribute epm_adc_in_attrs[] = {
1793 SENSOR_ATTR(ads0_chan0, S_IRUGO, epm_adc_show_in, NULL, 0),
1794 SENSOR_ATTR(ads0_chan1, S_IRUGO, epm_adc_show_in, NULL, 1),
1795 SENSOR_ATTR(ads0_chan2, S_IRUGO, epm_adc_show_in, NULL, 2),
1796 SENSOR_ATTR(ads0_chan3, S_IRUGO, epm_adc_show_in, NULL, 3),
1797 SENSOR_ATTR(ads0_chan4, S_IRUGO, epm_adc_show_in, NULL, 4),
1798 SENSOR_ATTR(ads0_chan5, S_IRUGO, epm_adc_show_in, NULL, 5),
1799 SENSOR_ATTR(ads0_chan6, S_IRUGO, epm_adc_show_in, NULL, 6),
1800 SENSOR_ATTR(ads0_chan7, S_IRUGO, epm_adc_show_in, NULL, 7),
1801 SENSOR_ATTR(ads0_chan8, S_IRUGO, epm_adc_show_in, NULL, 8),
1802 SENSOR_ATTR(ads0_chan9, S_IRUGO, epm_adc_show_in, NULL, 9),
1803 SENSOR_ATTR(ads0_chan10, S_IRUGO, epm_adc_show_in, NULL, 10),
1804 SENSOR_ATTR(ads0_chan11, S_IRUGO, epm_adc_show_in, NULL, 11),
1805 SENSOR_ATTR(ads0_chan12, S_IRUGO, epm_adc_show_in, NULL, 12),
1806 SENSOR_ATTR(ads0_chan13, S_IRUGO, epm_adc_show_in, NULL, 13),
1807 SENSOR_ATTR(ads0_chan14, S_IRUGO, epm_adc_show_in, NULL, 14),
1808 SENSOR_ATTR(ads0_chan15, S_IRUGO, epm_adc_show_in, NULL, 15),
1809 SENSOR_ATTR(ads1_chan0, S_IRUGO, epm_adc_show_in, NULL, 16),
1810 SENSOR_ATTR(ads1_chan1, S_IRUGO, epm_adc_show_in, NULL, 17),
1811 SENSOR_ATTR(ads1_chan2, S_IRUGO, epm_adc_show_in, NULL, 18),
1812 SENSOR_ATTR(ads1_chan3, S_IRUGO, epm_adc_show_in, NULL, 19),
1813 SENSOR_ATTR(ads1_chan4, S_IRUGO, epm_adc_show_in, NULL, 20),
1814 SENSOR_ATTR(ads1_chan5, S_IRUGO, epm_adc_show_in, NULL, 21),
1815 SENSOR_ATTR(ads1_chan6, S_IRUGO, epm_adc_show_in, NULL, 22),
1816 SENSOR_ATTR(ads1_chan7, S_IRUGO, epm_adc_show_in, NULL, 23),
1817 SENSOR_ATTR(ads1_chan8, S_IRUGO, epm_adc_show_in, NULL, 24),
1818 SENSOR_ATTR(ads1_chan9, S_IRUGO, epm_adc_show_in, NULL, 25),
1819 SENSOR_ATTR(ads1_chan10, S_IRUGO, epm_adc_show_in, NULL, 26),
1820 SENSOR_ATTR(ads1_chan11, S_IRUGO, epm_adc_show_in, NULL, 27),
1821 SENSOR_ATTR(ads1_chan12, S_IRUGO, epm_adc_show_in, NULL, 28),
1822 SENSOR_ATTR(ads1_chan13, S_IRUGO, epm_adc_show_in, NULL, 29),
1823 SENSOR_ATTR(ads1_chan14, S_IRUGO, epm_adc_show_in, NULL, 30),
1824 SENSOR_ATTR(ads1_chan15, S_IRUGO, epm_adc_show_in, NULL, 31),
1825};
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001826
1827static int __devinit epm_adc_init_hwmon(struct platform_device *pdev,
1828 struct epm_adc_drv *epm_adc)
1829{
1830 struct epm_adc_platform_data *pdata = pdev->dev.platform_data;
Stephen Boydaeaf2ad2012-07-03 14:33:25 -07001831 int i, rc, num_chans = pdata->num_channels;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001832
Stephen Boydaeaf2ad2012-07-03 14:33:25 -07001833 for (i = 0; i < num_chans; i++) {
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001834 rc = device_create_file(&pdev->dev,
Stephen Boydaeaf2ad2012-07-03 14:33:25 -07001835 &epm_adc_in_attrs[i].dev_attr);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001836 if (rc) {
1837 dev_err(&pdev->dev, "device_create_file failed\n");
1838 return rc;
1839 }
1840 }
1841
Stephen Boydaeaf2ad2012-07-03 14:33:25 -07001842 return 0;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001843}
1844
Stephen Boyd58701e82012-04-25 11:48:28 -07001845static int __devinit epm_adc_probe(struct platform_device *pdev)
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001846{
1847 struct epm_adc_drv *epm_adc;
1848 struct epm_adc_platform_data *pdata = pdev->dev.platform_data;
1849 int rc = 0;
1850
1851 if (!pdata) {
1852 dev_err(&pdev->dev, "no platform data?\n");
1853 return -EINVAL;
1854 }
1855
1856 epm_adc = kzalloc(sizeof(struct epm_adc_drv), GFP_KERNEL);
1857 if (!epm_adc) {
1858 dev_err(&pdev->dev, "Unable to allocate memory\n");
1859 return -ENOMEM;
1860 }
1861
1862 platform_set_drvdata(pdev, epm_adc);
1863 epm_adc_drv = epm_adc;
1864 epm_adc->pdev = pdev;
1865
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001866 epm_adc->misc.name = EPM_ADC_DRIVER_NAME;
1867 epm_adc->misc.minor = MISC_DYNAMIC_MINOR;
1868 epm_adc->misc.fops = &epm_adc_fops;
1869
1870 if (misc_register(&epm_adc->misc)) {
1871 dev_err(&pdev->dev, "Unable to register misc device!\n");
1872 return -EFAULT;
1873 }
1874
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001875 rc = epm_adc_init_hwmon(pdev, epm_adc);
1876 if (rc) {
1877 dev_err(&pdev->dev, "msm_adc_dev_init failed\n");
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001878 misc_deregister(&epm_adc->misc);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001879 return rc;
1880 }
1881
1882 epm_adc->hwmon = hwmon_device_register(&pdev->dev);
1883 if (IS_ERR(epm_adc->hwmon)) {
1884 dev_err(&pdev->dev, "hwmon_device_register failed\n");
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001885 misc_deregister(&epm_adc->misc);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001886 rc = PTR_ERR(epm_adc->hwmon);
1887 return rc;
1888 }
1889
1890 mutex_init(&epm_adc->conv_lock);
1891 epm_i2c_info = &pdata->epm_i2c_board_info;
1892 epm_adc->bus_id = pdata->bus_id;
1893 epm_gpio_expander_base_addr = pdata->gpio_expander_base_addr;
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001894 epm_adc_expander_register = false;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001895
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001896 return rc;
1897}
1898
1899static int __devexit epm_adc_remove(struct platform_device *pdev)
1900{
1901 struct epm_adc_drv *epm_adc = platform_get_drvdata(pdev);
1902 struct epm_adc_platform_data *pdata = pdev->dev.platform_data;
1903 int num_chans = pdata->num_channels;
1904 int i = 0;
1905
Stephen Boydaeaf2ad2012-07-03 14:33:25 -07001906 for (i = 0; i < num_chans; i++)
1907 device_remove_file(&pdev->dev, &epm_adc_in_attrs[i].dev_attr);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001908 hwmon_device_unregister(epm_adc->hwmon);
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001909 misc_deregister(&epm_adc->misc);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001910 epm_adc = NULL;
1911
1912 return 0;
1913}
1914
1915static struct platform_driver epm_adc_driver = {
1916 .probe = epm_adc_probe,
1917 .remove = __devexit_p(epm_adc_remove),
1918 .driver = {
1919 .name = EPM_ADC_DRIVER_NAME,
1920 .owner = THIS_MODULE,
1921 },
1922};
1923
1924static int __init epm_adc_init(void)
1925{
1926 int ret = 0;
1927
1928 ret = platform_driver_register(&epm_adc_driver);
1929 if (ret) {
1930 pr_err("%s: driver register failed, rc=%d\n", __func__, ret);
1931 return ret;
1932 }
1933
1934 ret = spi_register_driver(&epm_spi_driver);
1935 if (ret)
1936 pr_err("%s: spi register failed: rc=%d\n", __func__, ret);
1937
1938 return ret;
1939}
1940
1941static void __exit epm_adc_exit(void)
1942{
1943 spi_unregister_driver(&epm_spi_driver);
1944 platform_driver_unregister(&epm_adc_driver);
1945}
1946
1947module_init(epm_adc_init);
1948module_exit(epm_adc_exit);
1949
1950MODULE_DESCRIPTION("EPM ADC Driver");
1951MODULE_ALIAS("platform:epm_adc");
1952MODULE_LICENSE("GPL v2");