blob: 51ffd21538e643af5e1f267664a83277bbc83ef5 [file] [log] [blame]
Siddartha Mohanadoss899173a2013-01-29 19:18:50 -08001/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07002 *
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 Mohanadoss899173a2013-01-29 19:18:50 -0800589static int epm_psoc_scale_result(int16_t result, uint32_t index)
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700590{
591 struct epm_adc_drv *epm_adc = epm_adc_drv;
Siddartha Mohanadoss899173a2013-01-29 19:18:50 -0800592 int32_t result_cur, neg = 0;
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700593
Siddartha Mohanadossae7acf82012-12-12 10:36:07 -0800594 if ((1 << index) & epm_adc->channel_mask) {
Siddartha Mohanadoss899173a2013-01-29 19:18:50 -0800595 if (result & 0x800) {
596 neg = 1;
597 result = result & 0x7ff;
598 }
Siddartha Mohanadossae7acf82012-12-12 10:36:07 -0800599 /* result = (2.048V * code)/(4096 * gain * rsense) */
600 result_cur = ((EPM_PSOC_VREF_VOLTAGE * result)/
601 EPM_PSOC_MAX_ADC_CODE_12_BIT);
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700602
Siddartha Mohanadossae7acf82012-12-12 10:36:07 -0800603 result_cur = (result_cur/
604 (epm_adc->epm_psoc_ch_prop[index].gain *
605 epm_adc->epm_psoc_ch_prop[index].resistorvalue));
Siddartha Mohanadoss899173a2013-01-29 19:18:50 -0800606 if (neg)
607 result_cur -= result_cur;
Siddartha Mohanadossae7acf82012-12-12 10:36:07 -0800608 } else {
Siddartha Mohanadoss899173a2013-01-29 19:18:50 -0800609 if (result & 0x8000) {
610 neg = 1;
611 result = result & 0x7fff;
612 }
Siddartha Mohanadossae7acf82012-12-12 10:36:07 -0800613 /* result = (2.048V * code)/(32767 * gain * rsense) */
Siddartha Mohanadoss899173a2013-01-29 19:18:50 -0800614 result_cur = (((EPM_PSOC_VREF_VOLTAGE * (int) result)/
Siddartha Mohanadossae7acf82012-12-12 10:36:07 -0800615 EPM_PSOC_MAX_ADC_CODE_15_BIT) * 1000);
616
617 result_cur = (result_cur/
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700618 (epm_adc->epm_psoc_ch_prop[index].gain *
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700619 epm_adc->epm_psoc_ch_prop[index].resistorvalue));
Siddartha Mohanadoss899173a2013-01-29 19:18:50 -0800620 if (neg)
621 result_cur -= result_cur;
Siddartha Mohanadossae7acf82012-12-12 10:36:07 -0800622 }
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700623
624 return result_cur;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700625}
626
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -0700627static int epm_adc_blocking_conversion(struct epm_adc_drv *epm_adc,
628 struct epm_chan_request *conv)
629{
630 struct epm_adc_platform_data *pdata = epm_adc->pdev->dev.platform_data;
631 int32_t channel_num = 0, mux_chan_idx = 0;
632 char adc_data[3];
633 int rc = 0;
634
635 mutex_lock(&epm_adc->conv_lock);
636
637 rc = epm_adc_spi_chip_select(conv->device_idx);
638 if (rc) {
639 pr_err("epm_adc_chip_select failed, rc=%d\n", rc);
640 goto conv_err;
641 }
642
643 if (conv->channel_idx < pdata->chan_per_mux) {
644 /* Reset MUXSG1_REGISTER */
645 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_MUXSG1_REG_ADDR,
646 0x0);
647 if (rc)
648 goto conv_err;
649
650 mux_chan_idx = 1 << conv->channel_idx;
651 /* Select Channel index in MUXSG0_REGISTER */
652 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_MUXSG0_REG_ADDR,
653 mux_chan_idx);
654 if (rc)
655 goto conv_err;
656 } else {
657 /* Reset MUXSG0_REGISTER */
658 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_MUXSG0_REG_ADDR,
659 0x0);
660 if (rc)
661 goto conv_err;
662
663 mux_chan_idx = 1 << (conv->channel_idx - pdata->chan_per_mux);
664 /* Select Channel index in MUXSG1_REGISTER */
665 rc = epm_adc_ads_spi_write(epm_adc, EPM_ADC_ADS_MUXSG1_REG_ADDR,
666 mux_chan_idx);
667 if (rc)
668 goto conv_err;
669 }
670
671 rc = epm_adc_ads_pulse_convert(epm_adc);
672 if (rc) {
673 pr_err("epm_adc_ads_pulse_convert failed, rc=%d\n", rc);
674 goto conv_err;
675 }
676
677 rc = epm_adc_ads_read_data(epm_adc, adc_data);
678 if (rc) {
679 pr_err("epm_adc_ads_read_data failed, rc=%d\n", rc);
680 goto conv_err;
681 }
682
683 channel_num = (adc_data[0] & EPM_ADC_ADS_CHANNEL_DATA_CHID);
684 pr_debug("ADC data Read: adc_data =%d, %d, %d\n",
685 adc_data[0], adc_data[1], adc_data[2]);
686
687 epm_adc_ads_scale_result(epm_adc, (uint8_t *)adc_data, conv);
688
689 pr_debug("channel_num(0x) = %x, scaled_data = %d\n",
690 (channel_num - EPM_ADC_ADS_SPI_BITS_PER_WORD),
691 conv->physical);
692conv_err:
693 mutex_unlock(&epm_adc->conv_lock);
694 return rc;
695}
696
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700697static int epm_adc_psoc_gpio_init(bool enable)
698{
699 int rc = 0;
700
701 if (enable) {
702 rc = gpio_request(EPM_PSOC_GLOBAL_ENABLE, "EPM_PSOC_GLOBAL_EN");
703 if (!rc) {
704 gpio_direction_output(EPM_PSOC_GLOBAL_ENABLE, 1);
705 } else {
706 pr_err("%s: Configure EPM_GLOBAL_EN Failed\n",
707 __func__);
708 return rc;
709 }
710 } else {
711 gpio_direction_output(EPM_PSOC_GLOBAL_ENABLE, 0);
712 gpio_free(EPM_PSOC_GLOBAL_ENABLE);
713 }
714
715 return 0;
716}
717
718static int epm_psoc_init(struct epm_adc_drv *epm_adc,
719 struct epm_psoc_init_resp *init_resp)
720{
721 struct spi_message m;
722 struct spi_transfer t;
723 char tx_buf[17], rx_buf[17];
724 int rc = 0;
725
726 spi_setup(epm_adc->epm_spi_client);
727
728 memset(&t, 0, sizeof t);
729 memset(tx_buf, 0, sizeof tx_buf);
730 memset(rx_buf, 0, sizeof tx_buf);
731 t.tx_buf = tx_buf;
732 t.rx_buf = rx_buf;
733 spi_message_init(&m);
734 spi_message_add_tail(&t, &m);
735
736 tx_buf[0] = init_resp->cmd;
737
738 t.len = sizeof(tx_buf);
739 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
740
741 rc = spi_sync(epm_adc->epm_spi_client, &m);
742 if (rc)
743 return rc;
744
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700745 rc = spi_sync(epm_adc->epm_spi_client, &m);
746 if (rc)
747 return rc;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700748 init_resp->cmd = rx_buf[0];
749 init_resp->version = rx_buf[1];
750 init_resp->compatible_ver = rx_buf[2];
751 init_resp->firm_ver[0] = rx_buf[3];
752 init_resp->firm_ver[1] = rx_buf[4];
753 init_resp->firm_ver[2] = rx_buf[5];
754 init_resp->num_dev = rx_buf[6];
755 init_resp->num_channel = rx_buf[7];
756
757 return rc;
758}
759
760static int epm_psoc_channel_configure(struct epm_adc_drv *epm_adc,
761 struct epm_psoc_channel_configure *psoc_chan_configure)
762{
763 struct spi_message m;
764 struct spi_transfer t;
765 char tx_buf[9], rx_buf[9];
766 int32_t rc = 0, chan_num;
767
768 spi_setup(epm_adc->epm_spi_client);
769
770 memset(&t, 0, sizeof t);
771 memset(tx_buf, 0, sizeof tx_buf);
772 memset(rx_buf, 0, sizeof tx_buf);
773 t.tx_buf = tx_buf;
774 t.rx_buf = rx_buf;
775 spi_message_init(&m);
776 spi_message_add_tail(&t, &m);
777
778 chan_num = psoc_chan_configure->channel_num;
779
780 tx_buf[0] = psoc_chan_configure->cmd;
781 tx_buf[1] = 0;
782 tx_buf[2] = (chan_num & 0xff000000) >> 24;
783 tx_buf[3] = (chan_num & 0xff0000) >> 16;
784 tx_buf[4] = (chan_num & 0xff00) >> 8;
785 tx_buf[5] = (chan_num & 0xff);
786
787 t.len = sizeof(tx_buf);
788 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
789
790 rc = spi_sync(epm_adc->epm_spi_client, &m);
791 if (rc)
792 return rc;
793
794 rc = spi_sync(epm_adc->epm_spi_client, &m);
795 if (rc)
796 return rc;
797
798 psoc_chan_configure->cmd = rx_buf[0];
799 psoc_chan_configure->device_num = rx_buf[1];
800 chan_num = rx_buf[2] << 24 | (rx_buf[3] << 16) | (rx_buf[4] << 8) |
801 rx_buf[5];
802 psoc_chan_configure->channel_num = chan_num;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700803
804 return rc;
805}
806
807static int epm_psoc_set_averaging(struct epm_adc_drv *epm_adc,
808 struct epm_psoc_set_avg *psoc_set_avg)
809{
810 struct spi_message m;
811 struct spi_transfer t;
812 char tx_buf[4], rx_buf[4];
813 int rc = 0;
814
815 spi_setup(epm_adc->epm_spi_client);
816
817 memset(&t, 0, sizeof t);
818 memset(tx_buf, 0, sizeof tx_buf);
819 memset(rx_buf, 0, sizeof tx_buf);
820 t.tx_buf = tx_buf;
821 t.rx_buf = rx_buf;
822 spi_message_init(&m);
823 spi_message_add_tail(&t, &m);
824
825 tx_buf[0] = psoc_set_avg->cmd;
826 tx_buf[1] = psoc_set_avg->avg_period;
827
828 t.len = sizeof(tx_buf);
829 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
830
831 rc = spi_sync(epm_adc->epm_spi_client, &m);
832 if (rc)
833 return rc;
834
835 rc = spi_sync(epm_adc->epm_spi_client, &m);
836 if (rc)
837 return rc;
838
839 psoc_set_avg->cmd = rx_buf[0];
840 psoc_set_avg->return_code = rx_buf[1];
841
842 return rc;
843}
844
845static int epm_psoc_get_data(struct epm_adc_drv *epm_adc,
846 struct epm_psoc_get_data *psoc_get_meas)
847{
848 struct spi_message m;
849 struct spi_transfer t;
850 char tx_buf[10], rx_buf[10];
851 int rc = 0;
852
853 spi_setup(epm_adc->epm_spi_client);
854
855 memset(&t, 0, sizeof t);
856 memset(tx_buf, 0, sizeof tx_buf);
857 memset(rx_buf, 0, sizeof tx_buf);
858 t.tx_buf = tx_buf;
859 t.rx_buf = rx_buf;
860 spi_message_init(&m);
861 spi_message_add_tail(&t, &m);
862
863 tx_buf[0] = psoc_get_meas->cmd;
864 tx_buf[1] = psoc_get_meas->dev_num;
865 tx_buf[2] = psoc_get_meas->chan_num;
866
867 t.len = sizeof(tx_buf);
868 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
869
870 rc = spi_sync(epm_adc->epm_spi_client, &m);
871 if (rc)
872 return rc;
873
874 rc = spi_sync(epm_adc->epm_spi_client, &m);
875 if (rc)
876 return rc;
877
878 psoc_get_meas->cmd = rx_buf[0];
879 psoc_get_meas->dev_num = rx_buf[1];
880 psoc_get_meas->chan_num = rx_buf[2];
881 psoc_get_meas->timestamp_resp_value = (rx_buf[3] << 24) |
882 (rx_buf[4] << 16) | (rx_buf[5] << 8) |
883 rx_buf[6];
Siddartha Mohanadoss899173a2013-01-29 19:18:50 -0800884 psoc_get_meas->reading_raw = (rx_buf[7] << 8) | rx_buf[8];
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700885
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700886 return rc;
887}
888
889static int epm_psoc_get_buffered_data(struct epm_adc_drv *epm_adc,
890 struct epm_psoc_get_buffered_data *psoc_get_meas)
891{
892 struct spi_message m;
893 struct spi_transfer t;
894 char tx_buf[64], rx_buf[64];
895 int rc = 0, i;
896
897 spi_setup(epm_adc->epm_spi_client);
898
899 memset(&t, 0, sizeof t);
900 memset(tx_buf, 0, sizeof tx_buf);
901 memset(rx_buf, 0, sizeof tx_buf);
902 t.tx_buf = tx_buf;
903 t.rx_buf = rx_buf;
904 spi_message_init(&m);
905 spi_message_add_tail(&t, &m);
906
907 tx_buf[0] = psoc_get_meas->cmd;
908
909 t.len = sizeof(tx_buf);
910 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
911
912 rc = spi_sync(epm_adc->epm_spi_client, &m);
913 if (rc)
914 return rc;
915
916 rc = spi_sync(epm_adc->epm_spi_client, &m);
917 if (rc)
918 return rc;
919
920 psoc_get_meas->cmd = rx_buf[0];
921 psoc_get_meas->dev_num = rx_buf[1];
922 psoc_get_meas->status_mask = rx_buf[2];
923 psoc_get_meas->chan_idx = rx_buf[3];
924 psoc_get_meas->chan_mask = (rx_buf[4] << 24 |
925 rx_buf[5] << 16 | rx_buf[6] << 8
926 | rx_buf[7]);
927 psoc_get_meas->timestamp_start = (rx_buf[8] << 24 |
928 rx_buf[9] << 16 | rx_buf[10] << 8
929 | rx_buf[11]);
930 psoc_get_meas->timestamp_end = (rx_buf[12] << 24 |
931 rx_buf[13] << 16 | rx_buf[14] << 8
932 | rx_buf[15]);
933
934 for (i = 0; i < EPM_PSOC_BUFFERED_DATA_LENGTH; i++)
935 psoc_get_meas->buff_data[i] = rx_buf[16 + i];
936
937 return rc;
938}
939
940static int epm_psoc_timestamp(struct epm_adc_drv *epm_adc,
941 struct epm_psoc_system_time_stamp *psoc_timestamp)
942{
943 struct spi_message m;
944 struct spi_transfer t;
945 char tx_buf[10], rx_buf[10];
946 int rc = 0;
947
948 spi_setup(epm_adc->epm_spi_client);
949
950 memset(&t, 0, sizeof t);
951 memset(tx_buf, 0, sizeof tx_buf);
952 memset(rx_buf, 0, sizeof tx_buf);
953 t.tx_buf = tx_buf;
954 t.rx_buf = rx_buf;
955 spi_message_init(&m);
956 spi_message_add_tail(&t, &m);
957
958 if (psoc_timestamp->cmd == EPM_PSOC_SET_SYSTEM_TIMESTAMP_CMD) {
959 tx_buf[0] = psoc_timestamp->cmd;
960 tx_buf[1] = (psoc_timestamp->timestamp & 0xff000000) >> 24;
961 tx_buf[2] = (psoc_timestamp->timestamp & 0xff0000) >> 16;
962 tx_buf[3] = (psoc_timestamp->timestamp & 0xff00) >> 8;
963 tx_buf[4] = (psoc_timestamp->timestamp & 0xff);
964 } else if (psoc_timestamp->cmd == EPM_PSOC_GET_SYSTEM_TIMESTAMP_CMD) {
965 tx_buf[0] = psoc_timestamp->cmd;
966 }
967
968 t.len = sizeof(tx_buf);
969 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
970
971 rc = spi_sync(epm_adc->epm_spi_client, &m);
972 if (rc)
973 return rc;
974
975 rc = spi_sync(epm_adc->epm_spi_client, &m);
976 if (rc)
977 return rc;
978
979 psoc_timestamp->cmd = rx_buf[0];
980 psoc_timestamp->timestamp = rx_buf[1] << 24 | rx_buf[2] << 16 |
981 rx_buf[3] << 8 | rx_buf[4];
982
983 return rc;
984}
985
986static int epm_psoc_get_avg_buffered_switch_data(struct epm_adc_drv *epm_adc,
987 struct epm_psoc_get_avg_buffered_switch_data *psoc_get_meas)
988{
989 struct spi_message m;
990 struct spi_transfer t;
991 char tx_buf[64], rx_buf[64];
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -0700992 int rc = 0, i = 0, j = 0, z = 0;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -0700993
994 spi_setup(epm_adc->epm_spi_client);
995
996 memset(&t, 0, sizeof t);
997 memset(tx_buf, 0, sizeof tx_buf);
998 memset(rx_buf, 0, sizeof tx_buf);
999 t.tx_buf = tx_buf;
1000 t.rx_buf = rx_buf;
1001 spi_message_init(&m);
1002 spi_message_add_tail(&t, &m);
1003
1004 tx_buf[0] = psoc_get_meas->cmd;
1005
1006 t.len = sizeof(tx_buf);
1007 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
1008
1009 rc = spi_sync(epm_adc->epm_spi_client, &m);
1010 if (rc)
1011 return rc;
1012
1013 rc = spi_sync(epm_adc->epm_spi_client, &m);
1014 if (rc)
1015 return rc;
1016
1017 psoc_get_meas->cmd = rx_buf[0];
1018 psoc_get_meas->status = rx_buf[1];
1019 psoc_get_meas->timestamp_start = (rx_buf[2] << 24 |
1020 rx_buf[3] << 16 | rx_buf[4] << 8
1021 | rx_buf[5]);
1022 psoc_get_meas->channel_mask = (rx_buf[6] << 24 |
1023 rx_buf[7] << 16 | rx_buf[8] << 8
1024 | rx_buf[9]);
1025
1026 for (i = 0; i < EPM_PSOC_BUFFERED_DATA_LENGTH2; i++)
1027 psoc_get_meas->avg_data[i] = rx_buf[10 + i];
1028
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001029 i = j = 0;
1030 for (z = 0; z < 4; z++) {
1031 psoc_get_meas->data[i].channel = i;
1032 psoc_get_meas->data[i].avg_buffer_sample =
1033 rx_buf[10 + j] & EPM_AVG_BUF_MASK1;
1034 i++;
1035 j++;
1036 psoc_get_meas->data[i].avg_buffer_sample =
1037 rx_buf[10 + j] & EPM_AVG_BUF_MASK2;
1038 i++;
1039 j++;
1040 psoc_get_meas->data[i].avg_buffer_sample =
1041 rx_buf[10 + j] & EPM_AVG_BUF_MASK3;
1042 psoc_get_meas->data[i].avg_buffer_sample <<= 8;
1043 j++;
1044 psoc_get_meas->data[i].avg_buffer_sample =
1045 psoc_get_meas->data[i].avg_buffer_sample |
1046 (rx_buf[10 + j] & EPM_AVG_BUF_MASK4);
1047 i++;
1048 j++;
1049 psoc_get_meas->data[i].avg_buffer_sample =
1050 rx_buf[10 + j] & EPM_AVG_BUF_MASK5;
1051 i++;
1052 j++;
1053 psoc_get_meas->data[i].avg_buffer_sample =
1054 rx_buf[10 + j] & EPM_AVG_BUF_MASK6;
1055 i++;
1056 j++;
1057 psoc_get_meas->data[i].avg_buffer_sample =
1058 rx_buf[10 + j] & EPM_AVG_BUF_MASK7;
1059 psoc_get_meas->data[i].avg_buffer_sample <<= 4;
1060 j++;
1061 psoc_get_meas->data[i].avg_buffer_sample =
1062 psoc_get_meas->data[i].avg_buffer_sample |
1063 (rx_buf[10 + j] & EPM_AVG_BUF_MASK8);
1064 i++;
1065 j++;
1066 psoc_get_meas->data[i].avg_buffer_sample =
1067 rx_buf[10 + j] & EPM_AVG_BUF_MASK9;
1068 i++;
1069 j++;
1070 psoc_get_meas->data[i].avg_buffer_sample =
1071 rx_buf[10 + j] & EPM_AVG_BUF_MASK10;
1072 }
1073
1074 for (z = 0; z < 32; z++) {
1075 if (psoc_get_meas->data[z].avg_buffer_sample != 0)
1076 psoc_get_meas->data[z].result = epm_psoc_scale_result(
1077 psoc_get_meas->data[z].avg_buffer_sample, z);
1078 }
1079
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001080 return rc;
1081}
1082
1083static int epm_psoc_set_vadc(struct epm_adc_drv *epm_adc,
1084 struct epm_psoc_set_vadc *psoc_set_vadc)
1085{
1086 struct spi_message m;
1087 struct spi_transfer t;
1088 char tx_buf[10], rx_buf[10];
1089 int rc = 0;
1090
1091 spi_setup(epm_adc->epm_spi_client);
1092
1093 memset(&t, 0, sizeof t);
1094 memset(tx_buf, 0, sizeof tx_buf);
1095 memset(rx_buf, 0, sizeof tx_buf);
1096 t.tx_buf = tx_buf;
1097 t.rx_buf = rx_buf;
1098 spi_message_init(&m);
1099 spi_message_add_tail(&t, &m);
1100
1101 tx_buf[0] = psoc_set_vadc->cmd;
1102 tx_buf[1] = psoc_set_vadc->vadc_dev;
1103 tx_buf[2] = (psoc_set_vadc->vadc_voltage & 0xff000000) >> 24;
1104 tx_buf[3] = (psoc_set_vadc->vadc_voltage & 0xff0000) >> 16;
1105 tx_buf[4] = (psoc_set_vadc->vadc_voltage & 0xff00) >> 8;
1106 tx_buf[5] = psoc_set_vadc->vadc_voltage & 0xff;
1107
1108 t.len = sizeof(tx_buf);
1109 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
1110
1111 rc = spi_sync(epm_adc->epm_spi_client, &m);
1112 if (rc)
1113 return rc;
1114
1115 rc = spi_sync(epm_adc->epm_spi_client, &m);
1116 if (rc)
1117 return rc;
1118
1119 psoc_set_vadc->cmd = rx_buf[0];
1120 psoc_set_vadc->vadc_dev = rx_buf[1];
1121 psoc_set_vadc->vadc_voltage = (rx_buf[2] << 24) | (rx_buf[3] << 16) |
1122 (rx_buf[4] << 8) | (rx_buf[5]);
1123
1124 return rc;
1125}
1126
1127static int epm_psoc_set_channel_switch(struct epm_adc_drv *epm_adc,
1128 struct epm_psoc_set_channel_switch *psoc_channel_switch)
1129{
1130 struct spi_message m;
1131 struct spi_transfer t;
1132 char tx_buf[10], rx_buf[10];
1133 int rc = 0;
1134
1135 spi_setup(epm_adc->epm_spi_client);
1136
1137 memset(&t, 0, sizeof t);
1138 memset(tx_buf, 0, sizeof tx_buf);
1139 memset(rx_buf, 0, sizeof tx_buf);
1140 t.tx_buf = tx_buf;
1141 t.rx_buf = rx_buf;
1142 spi_message_init(&m);
1143 spi_message_add_tail(&t, &m);
1144
1145 tx_buf[0] = psoc_channel_switch->cmd;
1146 tx_buf[1] = psoc_channel_switch->dev;
1147 tx_buf[2] = (psoc_channel_switch->delay & 0xff000000) >> 24;
1148 tx_buf[3] = (psoc_channel_switch->delay & 0xff0000) >> 16;
1149 tx_buf[4] = (psoc_channel_switch->delay & 0xff00) >> 8;
1150 tx_buf[5] = psoc_channel_switch->delay & 0xff;
1151
1152 t.len = sizeof(tx_buf);
1153 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
1154
1155 rc = spi_sync(epm_adc->epm_spi_client, &m);
1156 if (rc)
1157 return rc;
1158
1159 rc = spi_sync(epm_adc->epm_spi_client, &m);
1160 if (rc)
1161 return rc;
1162
1163 psoc_channel_switch->cmd = rx_buf[0];
1164 psoc_channel_switch->dev = rx_buf[1];
1165 psoc_channel_switch->delay = rx_buf[2] << 24 |
1166 rx_buf[3] << 16 |
1167 rx_buf[4] << 8 | rx_buf[5];
1168
1169 return rc;
1170}
1171
1172static int epm_psoc_clear_buffer(struct epm_adc_drv *epm_adc)
1173{
1174 struct spi_message m;
1175 struct spi_transfer t;
1176 char tx_buf[3], rx_buf[3];
1177 int rc = 0;
1178
1179 spi_setup(epm_adc->epm_spi_client);
1180
1181 memset(&t, 0, sizeof t);
1182 memset(tx_buf, 0, sizeof tx_buf);
1183 memset(rx_buf, 0, sizeof tx_buf);
1184 t.tx_buf = tx_buf;
1185 t.rx_buf = rx_buf;
1186 spi_message_init(&m);
1187 spi_message_add_tail(&t, &m);
1188
1189 tx_buf[0] = EPM_PSOC_CLEAR_BUFFER_CMD;
1190
1191 t.len = sizeof(tx_buf);
1192 t.bits_per_word = EPM_ADC_ADS_SPI_BITS_PER_WORD;
1193
1194 rc = spi_sync(epm_adc->epm_spi_client, &m);
1195 if (rc)
1196 return rc;
1197
1198 rc = spi_sync(epm_adc->epm_spi_client, &m);
1199 if (rc)
1200 return rc;
1201
1202 rc = rx_buf[2];
1203
1204 return rc;
1205}
1206
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001207static long epm_adc_ioctl(struct file *file, unsigned int cmd,
1208 unsigned long arg)
1209{
1210 struct epm_adc_drv *epm_adc = epm_adc_drv;
1211
1212 switch (cmd) {
1213 case EPM_ADC_REQUEST:
1214 {
1215 struct epm_chan_request conv;
1216 int rc;
1217
1218 if (copy_from_user(&conv, (void __user *)arg,
1219 sizeof(struct epm_chan_request)))
1220 return -EFAULT;
1221
1222 rc = epm_adc_blocking_conversion(epm_adc, &conv);
1223 if (rc) {
1224 pr_err("Failed EPM conversion:%d\n", rc);
1225 return rc;
1226 }
1227
1228 if (copy_to_user((void __user *)arg, &conv,
1229 sizeof(struct epm_chan_request)))
1230 return -EFAULT;
1231 break;
1232 }
1233 case EPM_ADC_INIT:
1234 {
1235 uint32_t result;
1236 if (!epm_adc_expander_register) {
1237 result = epm_adc_i2c_expander_register();
1238 if (result) {
1239 pr_err("Failed i2c register:%d\n",
1240 result);
1241 return result;
1242 }
1243 epm_adc_expander_register = true;
1244 }
1245
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001246 result = epm_adc_hw_init(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 }
1253 case EPM_ADC_DEINIT:
1254 {
1255 uint32_t result;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001256 result = epm_adc_hw_deinit(epm_adc);
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001257
1258 if (copy_to_user((void __user *)arg, &result,
1259 sizeof(uint32_t)))
1260 return -EFAULT;
1261 break;
1262 }
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001263 case EPM_PSOC_ADC_INIT:
1264 {
1265 struct epm_psoc_init_resp psoc_init;
1266 int rc;
1267
1268 if (copy_from_user(&psoc_init, (void __user *)arg,
1269 sizeof(struct epm_psoc_init_resp)))
1270 return -EFAULT;
1271
1272 psoc_init.cmd = EPM_PSOC_INIT_CMD;
1273 rc = epm_psoc_init(epm_adc, &psoc_init);
1274 if (rc) {
1275 pr_err("PSOC initialization failed\n");
1276 return -EINVAL;
1277 }
1278
1279 if (copy_to_user((void __user *)arg, &psoc_init,
1280 sizeof(struct epm_psoc_init_resp)))
1281 return -EFAULT;
1282 break;
1283 }
1284 case EPM_PSOC_ADC_CHANNEL_ENABLE:
1285 case EPM_PSOC_ADC_CHANNEL_DISABLE:
1286 {
1287 struct epm_psoc_channel_configure psoc_chan_configure;
1288 int rc;
1289
1290 if (copy_from_user(&psoc_chan_configure,
1291 (void __user *)arg,
1292 sizeof(struct epm_psoc_channel_configure)))
1293 return -EFAULT;
1294
1295 psoc_chan_configure.cmd =
1296 EPM_PSOC_CHANNEL_ENABLE_DISABLE_CMD;
1297 rc = epm_psoc_channel_configure(epm_adc,
1298 &psoc_chan_configure);
1299 if (rc) {
1300 pr_err("PSOC channel configure failed\n");
1301 return -EINVAL;
1302 }
1303
1304 if (copy_to_user((void __user *)arg,
1305 &psoc_chan_configure,
1306 sizeof(struct epm_psoc_channel_configure)))
1307 return -EFAULT;
1308 break;
1309 }
1310 case EPM_PSOC_ADC_SET_AVERAGING:
1311 {
1312 struct epm_psoc_set_avg psoc_set_avg;
1313 int rc;
1314
1315 if (copy_from_user(&psoc_set_avg, (void __user *)arg,
1316 sizeof(struct epm_psoc_set_avg)))
1317 return -EFAULT;
1318
1319 psoc_set_avg.cmd = EPM_PSOC_SET_AVERAGING_CMD;
1320 rc = epm_psoc_set_averaging(epm_adc, &psoc_set_avg);
1321 if (rc) {
1322 pr_err("PSOC averaging failed\n");
1323 return -EINVAL;
1324 }
1325
1326 if (copy_to_user((void __user *)arg, &psoc_set_avg,
1327 sizeof(struct epm_psoc_set_avg)))
1328 return -EFAULT;
1329 break;
1330 }
1331 case EPM_PSOC_ADC_GET_LAST_MEASUREMENT:
1332 {
1333 struct epm_psoc_get_data psoc_get_data;
1334 int rc;
1335
1336 if (copy_from_user(&psoc_get_data,
1337 (void __user *)arg,
1338 sizeof(struct epm_psoc_get_data)))
1339 return -EFAULT;
1340
1341 psoc_get_data.cmd = EPM_PSOC_GET_LAST_MEASUREMENT_CMD;
1342 rc = epm_psoc_get_data(epm_adc, &psoc_get_data);
1343 if (rc) {
1344 pr_err("PSOC last measured data failed\n");
1345 return -EINVAL;
1346 }
1347
Siddartha Mohanadoss53c6ebe2012-12-06 14:17:30 -08001348 psoc_get_data.reading_value = epm_psoc_scale_result(
Siddartha Mohanadoss899173a2013-01-29 19:18:50 -08001349 psoc_get_data.reading_raw,
Siddartha Mohanadoss53c6ebe2012-12-06 14:17:30 -08001350 psoc_get_data.chan_num);
1351
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001352 if (copy_to_user((void __user *)arg, &psoc_get_data,
1353 sizeof(struct epm_psoc_get_data)))
1354 return -EFAULT;
1355 break;
1356 }
1357 case EPM_PSOC_ADC_GET_BUFFERED_DATA:
1358 {
1359 struct epm_psoc_get_buffered_data psoc_get_data;
1360 int rc;
1361
1362 if (copy_from_user(&psoc_get_data,
1363 (void __user *)arg,
1364 sizeof(struct epm_psoc_get_buffered_data)))
1365 return -EFAULT;
1366
1367 psoc_get_data.cmd = EPM_PSOC_GET_BUFFERED_DATA_CMD;
1368 rc = epm_psoc_get_buffered_data(epm_adc,
1369 &psoc_get_data);
1370 if (rc) {
1371 pr_err("PSOC buffered measurement failed\n");
1372 return -EINVAL;
1373 }
1374
1375 if (copy_to_user((void __user *)arg, &psoc_get_data,
1376 sizeof(struct epm_psoc_get_buffered_data)))
1377 return -EFAULT;
1378 break;
1379 }
1380 case EPM_PSOC_ADC_GET_SYSTEM_TIMESTAMP:
1381 case EPM_PSOC_ADC_SET_SYSTEM_TIMESTAMP:
1382 {
1383 struct epm_psoc_system_time_stamp psoc_timestamp;
1384 int rc;
1385
1386 if (copy_from_user(&psoc_timestamp,
1387 (void __user *)arg,
1388 sizeof(struct epm_psoc_system_time_stamp)))
1389 return -EFAULT;
1390
1391 rc = epm_psoc_timestamp(epm_adc, &psoc_timestamp);
1392 if (rc) {
1393 pr_err("PSOC buffered measurement failed\n");
1394 return -EINVAL;
1395 }
1396
1397 if (copy_to_user((void __user *)arg, &psoc_timestamp,
1398 sizeof(struct epm_psoc_system_time_stamp)))
1399 return -EFAULT;
1400 break;
1401 }
1402 case EPM_PSOC_ADC_GET_AVERAGE_DATA:
1403 {
1404 struct epm_psoc_get_avg_buffered_switch_data
1405 psoc_get_data;
1406 int rc;
1407
1408 if (copy_from_user(&psoc_get_data,
1409 (void __user *)arg,
1410 sizeof(struct
1411 epm_psoc_get_avg_buffered_switch_data)))
1412 return -EFAULT;
1413
1414 psoc_get_data.cmd = EPM_PSOC_GET_AVERAGED_DATA_CMD;
1415 rc = epm_psoc_get_avg_buffered_switch_data(epm_adc,
1416 &psoc_get_data);
1417 if (rc) {
1418 pr_err("Get averaged buffered data failed\n");
1419 return -EINVAL;
1420 }
1421
1422 if (copy_to_user((void __user *)arg, &psoc_get_data,
1423 sizeof(struct
1424 epm_psoc_get_avg_buffered_switch_data)))
1425 return -EFAULT;
1426 break;
1427 }
1428 case EPM_PSOC_SET_CHANNEL_SWITCH:
1429 {
1430 struct epm_psoc_set_channel_switch psoc_channel_switch;
1431 int rc;
1432
1433 if (copy_from_user(&psoc_channel_switch,
1434 (void __user *)arg,
1435 sizeof(struct epm_psoc_set_channel_switch)))
1436 return -EFAULT;
1437
1438 rc = epm_psoc_set_channel_switch(epm_adc,
1439 &psoc_channel_switch);
1440 if (rc) {
1441 pr_err("PSOC channel switch failed\n");
1442 return -EINVAL;
1443 }
1444
1445 if (copy_to_user((void __user *)arg,
1446 &psoc_channel_switch,
1447 sizeof(struct epm_psoc_set_channel_switch)))
1448 return -EFAULT;
1449 break;
1450 }
1451 case EPM_PSOC_CLEAR_BUFFER:
1452 {
1453 int rc;
1454 rc = epm_psoc_clear_buffer(epm_adc);
1455 if (rc) {
1456 pr_err("PSOC clear buffer failed\n");
1457 return -EINVAL;
1458 }
1459
1460 if (copy_to_user((void __user *)arg, &rc,
1461 sizeof(uint32_t)))
1462 return -EFAULT;
1463 break;
1464 }
1465 case EPM_PSOC_ADC_SET_VADC_REFERENCE:
1466 {
1467 struct epm_psoc_set_vadc psoc_set_vadc;
1468 int rc;
1469
1470 if (copy_from_user(&psoc_set_vadc,
1471 (void __user *)arg,
1472 sizeof(struct epm_psoc_set_vadc)))
1473 return -EFAULT;
1474
1475 rc = epm_psoc_set_vadc(epm_adc, &psoc_set_vadc);
1476 if (rc) {
1477 pr_err("PSOC set VADC failed\n");
1478 return -EINVAL;
1479 }
1480
1481 if (copy_to_user((void __user *)arg, &psoc_set_vadc,
1482 sizeof(struct epm_psoc_set_vadc)))
1483 return -EFAULT;
1484 break;
1485 }
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001486 default:
1487 return -EINVAL;
1488 }
1489
1490 return 0;
1491}
1492
1493const struct file_operations epm_adc_fops = {
1494 .unlocked_ioctl = epm_adc_ioctl,
1495};
1496
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001497static ssize_t epm_adc_psoc_show_in(struct device *dev,
1498 struct device_attribute *devattr, char *buf)
1499{
1500 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1501 struct epm_adc_drv *epm_adc = epm_adc_drv;
1502 struct epm_psoc_init_resp init_resp;
1503 struct epm_psoc_channel_configure psoc_chan_configure;
1504 struct epm_psoc_get_data psoc_get_meas;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001505 int rc = 0;
1506
1507 rc = epm_adc_psoc_gpio_init(true);
1508 if (rc) {
1509 pr_err("GPIO init failed\n");
1510 return 0;
1511 }
1512 usleep_range(EPM_GLOBAL_ENABLE_MIN_DELAY,
1513 EPM_GLOBAL_ENABLE_MAX_DELAY);
1514
1515 init_resp.cmd = EPM_PSOC_INIT_CMD;
1516 rc = epm_psoc_init(epm_adc, &init_resp);
1517 if (rc) {
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001518 pr_err("PSOC init failed %d\n", rc);
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001519 return 0;
1520 }
1521
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001522
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001523 psoc_chan_configure.channel_num = (1 << attr->index);
1524 psoc_chan_configure.cmd = EPM_PSOC_CHANNEL_ENABLE_DISABLE_CMD;
1525 rc = epm_psoc_channel_configure(epm_adc, &psoc_chan_configure);
1526 if (rc) {
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001527 pr_err("PSOC channel configure failed\n");
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001528 return 0;
1529 }
1530
1531 usleep_range(EPM_GLOBAL_ENABLE_MIN_DELAY,
1532 EPM_GLOBAL_ENABLE_MAX_DELAY);
1533
1534 psoc_get_meas.cmd = EPM_PSOC_GET_LAST_MEASUREMENT_CMD;
1535 psoc_get_meas.dev_num = 0;
1536 psoc_get_meas.chan_num = attr->index;
1537 rc = epm_psoc_get_data(epm_adc, &psoc_get_meas);
1538 if (rc) {
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001539 pr_err("PSOC get data failed\n");
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001540 return 0;
1541 }
1542
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001543 psoc_get_meas.reading_value = epm_psoc_scale_result(
1544 psoc_get_meas.reading_value,
1545 attr->index);
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001546
1547 rc = epm_adc_psoc_gpio_init(false);
1548 if (rc) {
1549 pr_err("GPIO de-init failed\n");
1550 return 0;
1551 }
1552
1553 return snprintf(buf, 16, "Result: %d\n", psoc_get_meas.reading_value);
1554}
1555
1556static struct sensor_device_attribute epm_adc_psoc_in_attrs[] = {
Siddartha Mohanadoss37e1c372012-12-06 14:19:11 -08001557 SENSOR_ATTR(psoc0_chan0, S_IRUGO, epm_adc_psoc_show_in, NULL, 0),
1558 SENSOR_ATTR(psoc0_chan1, S_IRUGO, epm_adc_psoc_show_in, NULL, 1),
1559 SENSOR_ATTR(psoc0_chan2, S_IRUGO, epm_adc_psoc_show_in, NULL, 2),
1560 SENSOR_ATTR(psoc0_chan3, S_IRUGO, epm_adc_psoc_show_in, NULL, 3),
1561 SENSOR_ATTR(psoc0_chan4, S_IRUGO, epm_adc_psoc_show_in, NULL, 4),
1562 SENSOR_ATTR(psoc0_chan5, S_IRUGO, epm_adc_psoc_show_in, NULL, 5),
1563 SENSOR_ATTR(psoc0_chan6, S_IRUGO, epm_adc_psoc_show_in, NULL, 6),
1564 SENSOR_ATTR(psoc0_chan7, S_IRUGO, epm_adc_psoc_show_in, NULL, 7),
1565 SENSOR_ATTR(psoc0_chan8, S_IRUGO, epm_adc_psoc_show_in, NULL, 8),
1566 SENSOR_ATTR(psoc0_chan9, S_IRUGO, epm_adc_psoc_show_in, NULL, 9),
1567 SENSOR_ATTR(psoc0_chan10, S_IRUGO, epm_adc_psoc_show_in, NULL, 10),
1568 SENSOR_ATTR(psoc0_chan11, S_IRUGO, epm_adc_psoc_show_in, NULL, 11),
1569 SENSOR_ATTR(psoc0_chan12, S_IRUGO, epm_adc_psoc_show_in, NULL, 12),
1570 SENSOR_ATTR(psoc0_chan13, S_IRUGO, epm_adc_psoc_show_in, NULL, 13),
1571 SENSOR_ATTR(psoc0_chan14, S_IRUGO, epm_adc_psoc_show_in, NULL, 14),
1572 SENSOR_ATTR(psoc0_chan15, S_IRUGO, epm_adc_psoc_show_in, NULL, 15),
1573 SENSOR_ATTR(psoc0_chan16, S_IRUGO, epm_adc_psoc_show_in, NULL, 16),
1574 SENSOR_ATTR(psoc0_chan17, S_IRUGO, epm_adc_psoc_show_in, NULL, 17),
1575 SENSOR_ATTR(psoc0_chan18, S_IRUGO, epm_adc_psoc_show_in, NULL, 18),
1576 SENSOR_ATTR(psoc0_chan19, S_IRUGO, epm_adc_psoc_show_in, NULL, 19),
1577 SENSOR_ATTR(psoc0_chan20, S_IRUGO, epm_adc_psoc_show_in, NULL, 20),
1578 SENSOR_ATTR(psoc0_chan21, S_IRUGO, epm_adc_psoc_show_in, NULL, 21),
1579 SENSOR_ATTR(psoc0_chan22, S_IRUGO, epm_adc_psoc_show_in, NULL, 22),
1580 SENSOR_ATTR(psoc0_chan23, S_IRUGO, epm_adc_psoc_show_in, NULL, 23),
1581 SENSOR_ATTR(psoc0_chan24, S_IRUGO, epm_adc_psoc_show_in, NULL, 24),
1582 SENSOR_ATTR(psoc0_chan25, S_IRUGO, epm_adc_psoc_show_in, NULL, 25),
1583 SENSOR_ATTR(psoc0_chan26, S_IRUGO, epm_adc_psoc_show_in, NULL, 26),
1584 SENSOR_ATTR(psoc0_chan27, S_IRUGO, epm_adc_psoc_show_in, NULL, 27),
1585 SENSOR_ATTR(psoc0_chan28, S_IRUGO, epm_adc_psoc_show_in, NULL, 28),
1586 SENSOR_ATTR(psoc0_chan29, S_IRUGO, epm_adc_psoc_show_in, NULL, 29),
1587 SENSOR_ATTR(psoc0_chan30, S_IRUGO, epm_adc_psoc_show_in, NULL, 30),
1588 SENSOR_ATTR(psoc0_chan31, S_IRUGO, epm_adc_psoc_show_in, NULL, 31),
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001589};
1590
1591static int __devinit epm_adc_psoc_init_hwmon(struct spi_device *spi,
1592 struct epm_adc_drv *epm_adc)
1593{
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001594 int i, rc, num_chans = 31;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001595
1596 for (i = 0; i < num_chans; i++) {
1597 rc = device_create_file(&spi->dev,
1598 &epm_adc_psoc_in_attrs[i].dev_attr);
1599 if (rc) {
1600 dev_err(&spi->dev, "device_create_file failed\n");
1601 return rc;
1602 }
1603 }
1604
1605 return 0;
1606}
1607
1608static int get_device_tree_data(struct spi_device *spi)
1609{
1610 const struct device_node *node = spi->dev.of_node;
1611 struct epm_adc_drv *epm_adc;
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001612 u32 *epm_ch_gain, *epm_ch_rsense;
1613 u32 rc = 0, epm_num_channels, i, channel_mask;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001614
1615 if (!node)
1616 return -EINVAL;
1617
1618 rc = of_property_read_u32(node,
1619 "qcom,channels", &epm_num_channels);
1620 if (rc) {
1621 dev_err(&spi->dev, "missing channel numbers\n");
1622 return -ENODEV;
1623 }
1624
1625 epm_ch_gain = devm_kzalloc(&spi->dev,
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001626 epm_num_channels * sizeof(u32), GFP_KERNEL);
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001627 if (!epm_ch_gain) {
1628 dev_err(&spi->dev, "cannot allocate gain\n");
1629 return -ENOMEM;
1630 }
1631
1632 epm_ch_rsense = devm_kzalloc(&spi->dev,
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001633 epm_num_channels * sizeof(u32), GFP_KERNEL);
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001634 if (!epm_ch_rsense) {
1635 dev_err(&spi->dev, "cannot allocate rsense\n");
1636 return -ENOMEM;
1637 }
1638
1639 rc = of_property_read_u32_array(node,
1640 "qcom,gain", epm_ch_gain, epm_num_channels);
1641 if (rc) {
1642 dev_err(&spi->dev, "invalid gain property:%d\n", rc);
1643 return rc;
1644 }
1645
1646 rc = of_property_read_u32_array(node,
1647 "qcom,rsense", epm_ch_rsense, epm_num_channels);
1648 if (rc) {
1649 dev_err(&spi->dev, "invalid rsense property:%d\n", rc);
1650 return rc;
1651 }
1652
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001653 rc = of_property_read_u32(node,
1654 "qcom,channel-type", &channel_mask);
1655 if (rc) {
1656 dev_err(&spi->dev, "missing channel mask\n");
1657 return -ENODEV;
1658 }
1659
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001660 epm_adc = devm_kzalloc(&spi->dev,
1661 sizeof(struct epm_adc_drv) +
1662 (epm_num_channels *
1663 sizeof(struct epm_chan_properties)),
1664 GFP_KERNEL);
1665 if (!epm_adc) {
1666 dev_err(&spi->dev, "Unable to allocate memory\n");
1667 return -ENOMEM;
1668 }
1669
1670 for (i = 0; i < epm_num_channels; i++) {
1671 epm_adc->epm_psoc_ch_prop[i].resistorvalue =
1672 epm_ch_rsense[i];
1673 epm_adc->epm_psoc_ch_prop[i].gain =
1674 epm_ch_gain[i];
1675 }
1676
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001677 epm_adc->channel_mask = channel_mask;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001678 epm_adc_drv = epm_adc;
1679
1680 return 0;
1681}
1682
1683static int __devinit epm_adc_psoc_spi_probe(struct spi_device *spi)
1684{
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001685
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001686 struct epm_adc_drv *epm_adc;
1687 struct device_node *node = spi->dev.of_node;
1688 int rc = 0;
1689
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001690 if (node) {
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001691 rc = get_device_tree_data(spi);
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001692 if (rc)
1693 return rc;
1694 } else {
Siddartha Mohanadossde90ed42012-09-18 16:57:50 -07001695 epm_adc = epm_adc_drv;
1696 epm_adc_drv->epm_spi_client = spi;
1697 epm_adc_drv->epm_spi_client->bits_per_word =
1698 EPM_ADC_ADS_SPI_BITS_PER_WORD;
1699 return rc;
1700 }
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001701
1702 epm_adc = epm_adc_drv;
1703 epm_adc->misc.name = EPM_ADC_DRIVER_NAME;
1704 epm_adc->misc.minor = MISC_DYNAMIC_MINOR;
Siddartha Mohanadoss5e8df032012-11-12 17:54:03 -08001705
1706 if (node) {
1707 epm_adc->misc.fops = &epm_adc_fops;
1708 if (misc_register(&epm_adc->misc)) {
1709 pr_err("Unable to register misc device!\n");
1710 return -EFAULT;
1711 }
1712 }
1713
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001714 epm_adc_drv->epm_spi_client = spi;
1715 epm_adc_drv->epm_spi_client->bits_per_word =
1716 EPM_ADC_ADS_SPI_BITS_PER_WORD;
1717 rc = epm_adc_psoc_init_hwmon(spi, epm_adc);
1718 if (rc) {
1719 dev_err(&spi->dev, "msm_adc_dev_init failed\n");
1720 return rc;
1721 }
1722
1723 epm_adc->hwmon = hwmon_device_register(&spi->dev);
1724 if (IS_ERR(epm_adc->hwmon)) {
1725 dev_err(&spi->dev, "hwmon_device_register failed\n");
1726 return rc;
1727 }
1728
1729 mutex_init(&epm_adc->conv_lock);
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001730 return rc;
1731}
1732
1733static int __devexit epm_adc_psoc_spi_remove(struct spi_device *spi)
1734{
1735 epm_adc_drv->epm_spi_client = NULL;
1736 return 0;
1737}
1738
1739static const struct of_device_id epm_adc_psoc_match_table[] = {
Siddartha Mohanadoss6eadd582012-10-25 15:29:22 -07001740 { .compatible = "cy,epm-adc-cy8c5568lti-114",
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001741 },
1742 {}
1743};
1744
1745static struct spi_driver epm_spi_driver = {
1746 .probe = epm_adc_psoc_spi_probe,
1747 .remove = __devexit_p(epm_adc_psoc_spi_remove),
1748 .driver = {
1749 .name = EPM_ADC_DRIVER_NAME,
1750 .of_match_table = epm_adc_psoc_match_table,
1751 },
1752};
1753
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001754static ssize_t epm_adc_show_in(struct device *dev,
1755 struct device_attribute *devattr, char *buf)
1756{
1757 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
1758 struct epm_adc_drv *epm_adc = dev_get_drvdata(dev);
1759 struct epm_adc_platform_data *pdata = epm_adc->pdev->dev.platform_data;
1760 struct epm_chan_request conv;
1761 int rc = 0;
1762
1763 conv.device_idx = attr->index / pdata->chan_per_adc;
1764 conv.channel_idx = attr->index % pdata->chan_per_adc;
1765 conv.physical = 0;
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001766
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001767 if (!epm_adc_expander_register) {
1768 rc = epm_adc_i2c_expander_register();
1769 if (rc) {
1770 pr_err("I2C expander register failed:%d\n", rc);
1771 return rc;
1772 }
1773 epm_adc_expander_register = true;
1774 }
1775
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001776 rc = epm_adc_hw_init(epm_adc);
1777 if (rc) {
1778 pr_err("%s: epm_adc_hw_init() failed, rc = %d",
1779 __func__, rc);
1780 return 0;
1781 }
1782
1783 rc = epm_adc_blocking_conversion(epm_adc, &conv);
1784 if (rc) {
1785 pr_err("%s: epm_adc_blocking_conversion() failed, rc = %d\n",
1786 __func__, rc);
1787 return 0;
1788 }
Siddartha Mohanadoss6e77b772012-09-19 21:58:13 -07001789
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001790 rc = epm_adc_hw_deinit(epm_adc);
1791 if (rc) {
1792 pr_err("%s: epm_adc_hw_deinit() failed, rc = %d",
1793 __func__, rc);
1794 return 0;
1795 }
1796
1797 return snprintf(buf, 16, "Result: %d\n", conv.physical);
1798}
1799
Stephen Boydaeaf2ad2012-07-03 14:33:25 -07001800static struct sensor_device_attribute epm_adc_in_attrs[] = {
1801 SENSOR_ATTR(ads0_chan0, S_IRUGO, epm_adc_show_in, NULL, 0),
1802 SENSOR_ATTR(ads0_chan1, S_IRUGO, epm_adc_show_in, NULL, 1),
1803 SENSOR_ATTR(ads0_chan2, S_IRUGO, epm_adc_show_in, NULL, 2),
1804 SENSOR_ATTR(ads0_chan3, S_IRUGO, epm_adc_show_in, NULL, 3),
1805 SENSOR_ATTR(ads0_chan4, S_IRUGO, epm_adc_show_in, NULL, 4),
1806 SENSOR_ATTR(ads0_chan5, S_IRUGO, epm_adc_show_in, NULL, 5),
1807 SENSOR_ATTR(ads0_chan6, S_IRUGO, epm_adc_show_in, NULL, 6),
1808 SENSOR_ATTR(ads0_chan7, S_IRUGO, epm_adc_show_in, NULL, 7),
1809 SENSOR_ATTR(ads0_chan8, S_IRUGO, epm_adc_show_in, NULL, 8),
1810 SENSOR_ATTR(ads0_chan9, S_IRUGO, epm_adc_show_in, NULL, 9),
1811 SENSOR_ATTR(ads0_chan10, S_IRUGO, epm_adc_show_in, NULL, 10),
1812 SENSOR_ATTR(ads0_chan11, S_IRUGO, epm_adc_show_in, NULL, 11),
1813 SENSOR_ATTR(ads0_chan12, S_IRUGO, epm_adc_show_in, NULL, 12),
1814 SENSOR_ATTR(ads0_chan13, S_IRUGO, epm_adc_show_in, NULL, 13),
1815 SENSOR_ATTR(ads0_chan14, S_IRUGO, epm_adc_show_in, NULL, 14),
1816 SENSOR_ATTR(ads0_chan15, S_IRUGO, epm_adc_show_in, NULL, 15),
1817 SENSOR_ATTR(ads1_chan0, S_IRUGO, epm_adc_show_in, NULL, 16),
1818 SENSOR_ATTR(ads1_chan1, S_IRUGO, epm_adc_show_in, NULL, 17),
1819 SENSOR_ATTR(ads1_chan2, S_IRUGO, epm_adc_show_in, NULL, 18),
1820 SENSOR_ATTR(ads1_chan3, S_IRUGO, epm_adc_show_in, NULL, 19),
1821 SENSOR_ATTR(ads1_chan4, S_IRUGO, epm_adc_show_in, NULL, 20),
1822 SENSOR_ATTR(ads1_chan5, S_IRUGO, epm_adc_show_in, NULL, 21),
1823 SENSOR_ATTR(ads1_chan6, S_IRUGO, epm_adc_show_in, NULL, 22),
1824 SENSOR_ATTR(ads1_chan7, S_IRUGO, epm_adc_show_in, NULL, 23),
1825 SENSOR_ATTR(ads1_chan8, S_IRUGO, epm_adc_show_in, NULL, 24),
1826 SENSOR_ATTR(ads1_chan9, S_IRUGO, epm_adc_show_in, NULL, 25),
1827 SENSOR_ATTR(ads1_chan10, S_IRUGO, epm_adc_show_in, NULL, 26),
1828 SENSOR_ATTR(ads1_chan11, S_IRUGO, epm_adc_show_in, NULL, 27),
1829 SENSOR_ATTR(ads1_chan12, S_IRUGO, epm_adc_show_in, NULL, 28),
1830 SENSOR_ATTR(ads1_chan13, S_IRUGO, epm_adc_show_in, NULL, 29),
1831 SENSOR_ATTR(ads1_chan14, S_IRUGO, epm_adc_show_in, NULL, 30),
1832 SENSOR_ATTR(ads1_chan15, S_IRUGO, epm_adc_show_in, NULL, 31),
1833};
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001834
1835static int __devinit epm_adc_init_hwmon(struct platform_device *pdev,
1836 struct epm_adc_drv *epm_adc)
1837{
1838 struct epm_adc_platform_data *pdata = pdev->dev.platform_data;
Stephen Boydaeaf2ad2012-07-03 14:33:25 -07001839 int i, rc, num_chans = pdata->num_channels;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001840
Stephen Boydaeaf2ad2012-07-03 14:33:25 -07001841 for (i = 0; i < num_chans; i++) {
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001842 rc = device_create_file(&pdev->dev,
Stephen Boydaeaf2ad2012-07-03 14:33:25 -07001843 &epm_adc_in_attrs[i].dev_attr);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001844 if (rc) {
1845 dev_err(&pdev->dev, "device_create_file failed\n");
1846 return rc;
1847 }
1848 }
1849
Stephen Boydaeaf2ad2012-07-03 14:33:25 -07001850 return 0;
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001851}
1852
Stephen Boyd58701e82012-04-25 11:48:28 -07001853static int __devinit epm_adc_probe(struct platform_device *pdev)
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001854{
1855 struct epm_adc_drv *epm_adc;
1856 struct epm_adc_platform_data *pdata = pdev->dev.platform_data;
1857 int rc = 0;
1858
1859 if (!pdata) {
1860 dev_err(&pdev->dev, "no platform data?\n");
1861 return -EINVAL;
1862 }
1863
1864 epm_adc = kzalloc(sizeof(struct epm_adc_drv), GFP_KERNEL);
1865 if (!epm_adc) {
1866 dev_err(&pdev->dev, "Unable to allocate memory\n");
1867 return -ENOMEM;
1868 }
1869
1870 platform_set_drvdata(pdev, epm_adc);
1871 epm_adc_drv = epm_adc;
1872 epm_adc->pdev = pdev;
1873
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001874 epm_adc->misc.name = EPM_ADC_DRIVER_NAME;
1875 epm_adc->misc.minor = MISC_DYNAMIC_MINOR;
1876 epm_adc->misc.fops = &epm_adc_fops;
1877
1878 if (misc_register(&epm_adc->misc)) {
1879 dev_err(&pdev->dev, "Unable to register misc device!\n");
1880 return -EFAULT;
1881 }
1882
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001883 rc = epm_adc_init_hwmon(pdev, epm_adc);
1884 if (rc) {
1885 dev_err(&pdev->dev, "msm_adc_dev_init failed\n");
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001886 misc_deregister(&epm_adc->misc);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001887 return rc;
1888 }
1889
1890 epm_adc->hwmon = hwmon_device_register(&pdev->dev);
1891 if (IS_ERR(epm_adc->hwmon)) {
1892 dev_err(&pdev->dev, "hwmon_device_register failed\n");
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001893 misc_deregister(&epm_adc->misc);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001894 rc = PTR_ERR(epm_adc->hwmon);
1895 return rc;
1896 }
1897
1898 mutex_init(&epm_adc->conv_lock);
1899 epm_i2c_info = &pdata->epm_i2c_board_info;
1900 epm_adc->bus_id = pdata->bus_id;
1901 epm_gpio_expander_base_addr = pdata->gpio_expander_base_addr;
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001902 epm_adc_expander_register = false;
Siddartha Mohanadossefddea42012-09-04 08:23:43 -07001903
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001904 return rc;
1905}
1906
1907static int __devexit epm_adc_remove(struct platform_device *pdev)
1908{
1909 struct epm_adc_drv *epm_adc = platform_get_drvdata(pdev);
1910 struct epm_adc_platform_data *pdata = pdev->dev.platform_data;
1911 int num_chans = pdata->num_channels;
1912 int i = 0;
1913
Stephen Boydaeaf2ad2012-07-03 14:33:25 -07001914 for (i = 0; i < num_chans; i++)
1915 device_remove_file(&pdev->dev, &epm_adc_in_attrs[i].dev_attr);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001916 hwmon_device_unregister(epm_adc->hwmon);
Siddartha Mohanadosseb90c922012-03-27 22:58:06 -07001917 misc_deregister(&epm_adc->misc);
Siddartha Mohanadoss53c16f92011-10-17 15:57:15 -07001918 epm_adc = NULL;
1919
1920 return 0;
1921}
1922
1923static struct platform_driver epm_adc_driver = {
1924 .probe = epm_adc_probe,
1925 .remove = __devexit_p(epm_adc_remove),
1926 .driver = {
1927 .name = EPM_ADC_DRIVER_NAME,
1928 .owner = THIS_MODULE,
1929 },
1930};
1931
1932static int __init epm_adc_init(void)
1933{
1934 int ret = 0;
1935
1936 ret = platform_driver_register(&epm_adc_driver);
1937 if (ret) {
1938 pr_err("%s: driver register failed, rc=%d\n", __func__, ret);
1939 return ret;
1940 }
1941
1942 ret = spi_register_driver(&epm_spi_driver);
1943 if (ret)
1944 pr_err("%s: spi register failed: rc=%d\n", __func__, ret);
1945
1946 return ret;
1947}
1948
1949static void __exit epm_adc_exit(void)
1950{
1951 spi_unregister_driver(&epm_spi_driver);
1952 platform_driver_unregister(&epm_adc_driver);
1953}
1954
1955module_init(epm_adc_init);
1956module_exit(epm_adc_exit);
1957
1958MODULE_DESCRIPTION("EPM ADC Driver");
1959MODULE_ALIAS("platform:epm_adc");
1960MODULE_LICENSE("GPL v2");