blob: 81d5b54bfe729ecab61fd19dd925a976f5726cf1 [file] [log] [blame]
Flemmard939472a2014-02-21 20:23:00 +01001/*
2 * Includes
3 */
4#include <linux/init.h>
5#include <linux/module.h>
6#include <linux/kernel.h>
7#include <linux/sched.h>
8#include <linux/errno.h>
9#include <linux/list.h>
10#include <linux/wait.h>
11#include <linux/spinlock.h>
12#include <linux/delay.h>
13#include <linux/interrupt.h>
14#include <linux/platform_device.h>
15#include <linux/input.h>
16#include <linux/wait.h>
17#include <linux/bitops.h>
18#include <linux/ctype.h>
19#include <linux/slab.h>
20#include <linux/a6_sbw_interface.h>
21#include <linux/a6.h>
22#ifdef CONFIG_HIGH_RES_TIMERS
23#include <linux/hrtimer.h>
24#endif
25#include <linux/cpufreq.h>
26#include <linux/i2c.h>
27#include <linux/workqueue.h>
28#include <linux/mutex.h>
29#include <linux/sysfs.h>
30#include <linux/uaccess.h>
31#include <linux/types.h>
32#include <linux/miscdevice.h>
33#include <linux/fs.h>
34#include <linux/poll.h>
35#include <asm/io.h>
36#include <linux/gpio.h>
37#include <linux/cdev.h>
38#include <linux/debugfs.h>
39#include <linux/switch.h>
40#include <linux/power_supply.h>
41#include <mach/msm_hsusb.h>
42#include <linux/max8903b_charger.h>
43
44#include "high_level_funcs.h"
45
46void max8903b_set_connected_ps(unsigned connected);
47
48#define A2A_RD_BUFF_SIZE (4 * 1024)
49#define A2A_WR_BUFF_SIZE (4 * 1024)
50
51#define A6_DEBUG
52#define A6_PQ
53//#define A6_I2C_RETRY
54
55#ifdef A6_DEBUG
56#define ASSERT(i) BUG_ON(!(i))
57
58#else
59#define ASSERT(i) ((void)0)
60
61#endif
62
63
64enum {
65 A6_DEBUG_VERBOSE = 0x01,
66};
67
68static int a6_debug_mask = 0x0;
69static int a6_tp_irq_count = 0;
70static int a6_t2s_dup_correct = 0;
71static int a6_disable_dock_switch = 0;
72
73static int param_set_disable_dock_switch(const char *val, struct kernel_param *kp);
74param_check_int(disable_dock_switch, &(a6_disable_dock_switch));
75module_param_call(disable_dock_switch, param_set_disable_dock_switch,
76 param_get_int, &a6_disable_dock_switch,
77 S_IRUGO | S_IWUSR | S_IWGRP
78 );
79__MODULE_PARM_TYPE(disable_dock_switch, int);
80
81module_param_named(
82 debug_mask, a6_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP
83 );
84
85module_param_named(
86 a6_irq_count, a6_tp_irq_count, int, S_IRUGO | S_IWUSR | S_IWGRP
87 );
88
89module_param_named(
90 t2s_dup_correct, a6_t2s_dup_correct, int, S_IRUGO | S_IWUSR | S_IWGRP
91 );
92
93#define A6_DPRINTK(mask, level, message, ...) \
94 do { \
95 if ((mask) & a6_debug_mask) \
96 printk(level message , ##__VA_ARGS__); \
97} while (0)
98
99#define PROFILE_USAGE
100#if defined PROFILE_USAGE
101bool reset_active = false;
102uint32_t start_time;
103int32_t diff_time;
104
105uint32_t start_last_a6_activity = 0;
106#endif
107
108long a6_last_ps_connect = 0;
109
110/* page 0x00 */
111/* host interrupts */
112#define TS2_I2C_INT_MASK_0 0x0000
113#define TS2_I2C_INT_MASK_1 0x0001
114#define TS2_I2C_INT_MASK_2 0x0002
115#define TS2_I2C_INT_MASK_3 0x0003
116#define TS2_I2C_INT_STATUS_0 0x0004
117#define TS2_I2C_INT_STATUS_1 0x0005
118#define TS2_I2C_INT_STATUS_2 0x0006
119#define TS2_I2C_INT_STATUS_3 0x0007
120#define TS2_I2C_INT_0_GPIOA_7 0x80
121#define TS2_I2C_INT_0_GPIOA_6 0x40
122#define TS2_I2C_INT_0_GPIOA_5 0x20
123#define TS2_I2C_INT_0_GPIOA_4 0x10
124#define TS2_I2C_INT_0_GPIOA_3 0x08
125#define TS2_I2C_INT_0_GPIOA_2 0x04
126#define TS2_I2C_INT_0_GPIOA_1 0x02
127#define TS2_I2C_INT_0_GPIOA_0 0x01
128#define TS2_I2C_INT_0_GPIOA_MASK 0xff
129#define TS2_I2C_INT_1_COMM_RX_FULL 0x02
130#define TS2_I2C_INT_1_COMM_TX_EMPTY 0x01
131#define TS2_I2C_INT_2_BAT_TEMP_HIGH 0x20
132#define TS2_I2C_INT_2_BAT_TEMP_LOW 0x10
133#define TS2_I2C_INT_2_BAT_VOLT_LOW 0x08
134#define TS2_I2C_INT_2_BAT_RARC_CRIT 0x04
135#define TS2_I2C_INT_2_BAT_RARC_LOW2 0x02
136#define TS2_I2C_INT_2_BAT_RARC_LOW1 0x01
137#define TS2_I2C_INT_3_A2A_CONNECT_CHANGE 0x08
138#define TS2_I2C_INT_3_FLAGS_CHANGE 0x04
139#define TS2_I2C_INT_3_LOG 0x02
140#define TS2_I2C_INT_3_RESET 0x01
141
142
143/* page 0x01 */
144/* battery (airboard only); interface defined by phone teams */
145#define TS2_I2C_BAT_STATUS 0x0100
146#define TS2_I2C_BAT_RARC 0x0101
147#define TS2_I2C_BAT_RSRC 0x0102
148#define TS2_I2C_BAT_AVG_CUR_MSB 0x0103
149#define TS2_I2C_BAT_AVG_CUR_LSB 0x0104
150#define TS2_I2C_BAT_TEMP_MSB 0x0105
151#define TS2_I2C_BAT_TEMP_LSB 0x0106
152#define TS2_I2C_BAT_VOLT_MSB 0x0107
153#define TS2_I2C_BAT_VOLT_LSB 0x0108
154#define TS2_I2C_BAT_CUR_MSB 0x0109
155#define TS2_I2C_BAT_CUR_LSB 0x010a
156#define TS2_I2C_BAT_COULOMB_MSB 0x010b
157#define TS2_I2C_BAT_COULOMB_LSB 0x010c
158#define TS2_I2C_BAT_AS 0x010d
159#define TS2_I2C_BAT_FULL_MSB 0x010e
160#define TS2_I2C_BAT_FULL_LSB 0x010f
161#define TS2_I2C_BAT_FULL40_MSB 0x0110
162#define TS2_I2C_BAT_FULL40_LSB 0x0111
163#define TS2_I2C_BAT_RSNSP 0x0112
164#define TS2_I2C_BAT_RAAC_MSB 0x0113
165#define TS2_I2C_BAT_RAAC_LSB 0x0114
166#define TS2_I2C_BAT_SACR_MSB 0x0115
167#define TS2_I2C_BAT_SACR_LSB 0x0116
168#define TS2_I2C_BAT_ASL 0x0117
169#define TS2_I2C_BAT_FAC_MSB 0x0118
170#define TS2_I2C_BAT_FAC_LSB 0x0119
171
172#define TS2_I2C_BAT_ROMID_0 0x0120
173#define TS2_I2C_BAT_ROMID(x) \
174 (TS2_I2C_BAT_ROMID_0 + (x))
175
176#define TS2_I2C_BAT_COMMAND_STATUS 0x0140
177#define TS2_I2C_BAT_COMMAND_AUTH 0x81
178#define TS2_I2C_BAT_COMMAND_REFRESH 0x82
179#define TS2_I2C_BAT_COMMAND_WAKE 0x83
180#define TS2_I2C_BAT_COMMAND_OFF 0xe9
181#define TS2_I2C_BAT_STATUS_AUTH_FAIL 0x08
182#define TS2_I2C_BAT_STATUS_AUTH_PASS 0x04
183#define TS2_I2C_BAT_STATUS_REGS_VALID 0x02
184#define TS2_I2C_BAT_STATUS_BUSY 0x01
185
186
187/* battery configuration (airboard only) */
188#define TS2_I2C_BAT_TEMP_LOW_MSB 0x0180
189#define TS2_I2C_BAT_TEMP_LOW_LSB 0x0181
190#define TS2_I2C_BAT_TEMP_HIGH_MSB 0x0182
191#define TS2_I2C_BAT_TEMP_HIGH_LSB 0x0183
192#define TS2_I2C_BAT_VOLT_LOW_MSB 0x0184
193#define TS2_I2C_BAT_VOLT_LOW_LSB 0x0185
194#define TS2_I2C_BAT_RARC_CRIT 0x0186
195#define TS2_I2C_BAT_RARC_LOW_2 0x0187
196#define TS2_I2C_BAT_RARC_LOW_1 0x0188
197
198#define TS2_I2C_BAT_CHALLENGE_0 0x01e0
199#define TS2_I2C_BAT_CHALLENGE(x) \
200 (TS2_I2C_BAT_CHALLENGE_0 + (x))
201#define TS2_I2C_BAT_RESPONSE_0 \
202 (TS2_I2C_BAT_CHALLENGE_0 + 8)
203#define TS2_I2C_BAT_RESPONSE(x) \
204 (TS2_I2C_BAT_RESPONSE_0 + (x))
205
206
207/* page 0x02 */
208/* comms */
209#define TS2_I2C_COMM_STATUS 0x0200
210#define TS2_I2C_COMM_STATUS_RX_FULL 0x02
211#define TS2_I2C_COMM_STATUS_TX_EMPTY 0x01
212#define TS2_I2C_COMM_TXDATA_RXDATA_RESERVED_1 0x0201 /* reserved 1 */
213#define TS2_I2C_COMM_TXDATA_RXDATA_RESERVED_2 0x0202 /* reserved 2 */
214#define TS2_I2C_COMM_TXDATA_RXDATA 0x0203 /* side-effect */
215
216/* page 0x03 */
217/* log */
218#define TS2_I2C_LOG_LEVEL 0x0300
219#define TS2_I2C_LOG_INT_THRESHOLD 0x0301
220#define TS2_I2C_LOG_LOST_MSB_RESERVED_1 0x0302 /* reserved 1 */
221#define TS2_I2C_LOG_LOST_MSB_RESERVED_2 0x0303 /* reserved 2 */
222#define TS2_I2C_LOG_LOST_MSB 0x0304 /* side-effect */
223#define TS2_I2C_LOG_LOST_LSB 0x0305
224#define TS2_I2C_LOG_COUNT_MSB 0x0306
225#define TS2_I2C_LOG_COUNT_LSB 0x0307
226#define TS2_I2C_LOG_ENTRY_MSB_RESERVED_1 0x0308 /* reserved 1 */
227#define TS2_I2C_LOG_ENTRY_MSB_RESERVED_2 0x0309 /* reserved 2 */
228#define TS2_I2C_LOG_ENTRY_MSB 0x030a /* side-effect */
229#define TS2_I2C_LOG_ENTRY_LSB 0x030b
230
231
232/* page 0x04 */
233/* local enumeration structure */
234/* Enumeration registers (local) */
235#define TS2_I2C_ENUM_STRUCT_VER 0x0400
236#define TS2_I2C_ENUM_STRUCT_LEN 0x0401
237#define TS2_I2C_ENUM_PROTOCOL_MAP_VER 0x0402
238#define TS2_I2C_ENUM_MFGR_ID_HI 0x0403
239#define TS2_I2C_ENUM_MFGR_ID_LO 0x0404
240#define TS2_I2C_ENUM_PRODUCT_TYPE_HI 0x0405
241#define TS2_I2C_ENUM_PRODUCT_TYPE_LO 0x0406
242#define TS2_I2C_ENUM_SERNO_7 0x0407
243#define TS2_I2C_ENUM_SERNO_6 0x0408
244#define TS2_I2C_ENUM_SERNO_5 0x0409
245#define TS2_I2C_ENUM_SERNO_4 0x040A
246#define TS2_I2C_ENUM_SERNO_3 0x040B
247#define TS2_I2C_ENUM_SERNO_2 0x040C
248#define TS2_I2C_ENUM_SERNO_1 0x040D
249#define TS2_I2C_ENUM_SERNO_0 0x040E
250#define TS2_I2C_ENUM_ASSY_REV 0x040F
251#define TS2_I2C_ENUM_FW_VER_2 0x0410
252#define TS2_I2C_ENUM_FW_VER_1 0x0411
253#define TS2_I2C_ENUM_FW_VER_0 0x0412
254#define TS2_I2C_ENUM_VNODE_MIN_HI 0x0413
255#define TS2_I2C_ENUM_VNODE_MIN_LO 0x0414
256#define TS2_I2C_ENUM_VNODE_MAX_HI 0x0415
257#define TS2_I2C_ENUM_VNODE_MAX_LO 0x0416
258#define TS2_I2C_ENUM_INODE_MIN_HI 0x0417
259#define TS2_I2C_ENUM_INODE_MIN_LO 0x0418
260#define TS2_I2C_ENUM_INODE_MAX_HI 0x0419
261#define TS2_I2C_ENUM_INODE_MAX_LO 0x041A
262#define TS2_I2C_ENUM_TNODE_MIN 0x041B
263#define TS2_I2C_ENUM_TNODE_MAX 0x041C
264#define TS2_I2C_ENUM_POWER_MAX 0x041D
265
266#define TS2_I2C_ENUM_ACCE_0 0x0428
267#define TS2_I2C_ENUM_ACCE_1 0x0429
268#define TS2_I2C_ENUM_ACCE_2 0x042A
269#define TS2_I2C_ENUM_ACCE_3 0x042B
270#define TS2_I2C_ENUM_ACCE_4 0x042C
271#define TS2_I2C_ENUM_ACCE_5 0x042D
272#define TS2_I2C_ENUM_ACCE_6 0x042E
273#define TS2_I2C_ENUM_ACCE_7 0x042F
274#define TS2_I2C_ENUM_ACCE_8 0x0430
275#define TS2_I2C_ENUM_ACCE_9 0x0431
276#define TS2_I2C_ENUM_ACCE_10 0x0432
277#define TS2_I2C_ENUM_ACCE_11 0x0433
278#define TS2_I2C_ENUM_ACCE_12 0x0434
279#define TS2_I2C_ENUM_ACCE_13 0x0435
280#define TS2_I2C_ENUM_ACCE_14 0x0436
281#define TS2_I2C_ENUM_ACCE_15 0x0437
282#define TS2_I2C_ENUM_MIN_PWM 0x0438
283
284
285/* page 0x05 */
286/* remote enumeration structure */
287#define TS2_I2C_ENUM_REMOTE_STRUCT_VER 0x0500
288#define TS2_I2C_ENUM_REMOTE_STRUCT_LEN 0x0501
289#define TS2_I2C_ENUM_REMOTE_PROTOCOL_MAP_VER 0x0502
290#define TS2_I2C_ENUM_REMOTE_MFGR_ID_HI 0x0503
291#define TS2_I2C_ENUM_REMOTE_MFGR_ID_LO 0x0504
292#define TS2_I2C_ENUM_REMOTE_MFGR_ID_HI_V1 0x0505
293#define TS2_I2C_ENUM_REMOTE_MFGR_ID_LO_V1 0x0506
294#define TS2_I2C_ENUM_REMOTE_PRODUCT_TYPE_HI 0x0505
295#define TS2_I2C_ENUM_REMOTE_PRODUCT_TYPE_LO 0x0506
296#define TS2_I2C_ENUM_REMOTE_PRODUCT_TYPE_HI_V1 0x0507
297#define TS2_I2C_ENUM_REMOTE_PRODUCT_TYPE_LO_V1 0x0508
298#define TS2_I2C_ENUM_REMOTE_SERNO_7 0x0507
299#define TS2_I2C_ENUM_REMOTE_SERNO_6 0x0508
300#define TS2_I2C_ENUM_REMOTE_SERNO_5 0x0509
301#define TS2_I2C_ENUM_REMOTE_SERNO_4 0x050A
302#define TS2_I2C_ENUM_REMOTE_SERNO_3 0x050B
303#define TS2_I2C_ENUM_REMOTE_SERNO_2 0x050C
304#define TS2_I2C_ENUM_REMOTE_SERNO_1 0x050D
305#define TS2_I2C_ENUM_REMOTE_SERNO_0 0x050E
306#define TS2_I2C_ENUM_REMOTE_ASSY_REV 0x050F
307#define TS2_I2C_ENUM_REMOTE_FW_VER_2 0x0510
308#define TS2_I2C_ENUM_REMOTE_FW_VER_1 0x0511
309#define TS2_I2C_ENUM_REMOTE_FW_VER_0 0x0512
310#define TS2_I2C_ENUM_REMOTE_VNODE_MIN_HI 0x0513
311#define TS2_I2C_ENUM_REMOTE_VNODE_MIN_LO 0x0514
312#define TS2_I2C_ENUM_REMOTE_VNODE_MAX_HI 0x0515
313#define TS2_I2C_ENUM_REMOTE_VNODE_MAX_LO 0x0516
314#define TS2_I2C_ENUM_REMOTE_INODE_MIN_HI 0x0517
315#define TS2_I2C_ENUM_REMOTE_INODE_MIN_LO 0x0518
316#define TS2_I2C_ENUM_REMOTE_INODE_MAX_HI 0x0519
317#define TS2_I2C_ENUM_REMOTE_INODE_MAX_LO 0x051A
318#define TS2_I2C_ENUM_REMOTE_TNODE_MIN 0x051B
319#define TS2_I2C_ENUM_REMOTE_TNODE_MAX 0x051C
320#define TS2_I2C_ENUM_REMOTE_POWER_MAX 0x051D
321
322
323
324#define TS2_I2C_ENUM_REMOTE_ACCE_0 0x0528
325#define TS2_I2C_ENUM_REMOTE_ACCE_1 0x0529
326#define TS2_I2C_ENUM_REMOTE_ACCE_2 0x052A
327#define TS2_I2C_ENUM_REMOTE_ACCE_3 0x052B
328#define TS2_I2C_ENUM_REMOTE_ACCE_4 0x052C
329#define TS2_I2C_ENUM_REMOTE_ACCE_5 0x052D
330#define TS2_I2C_ENUM_REMOTE_ACCE_6 0x052E
331#define TS2_I2C_ENUM_REMOTE_ACCE_7 0x052F
332#define TS2_I2C_ENUM_REMOTE_ACCE_8 0x0530
333#define TS2_I2C_ENUM_REMOTE_ACCE_9 0x0531
334#define TS2_I2C_ENUM_REMOTE_ACCE_10 0x0532
335#define TS2_I2C_ENUM_REMOTE_ACCE_11 0x0533
336#define TS2_I2C_ENUM_REMOTE_ACCE_12 0x0534
337#define TS2_I2C_ENUM_REMOTE_ACCE_13 0x0535
338#define TS2_I2C_ENUM_REMOTE_ACCE_14 0x0536
339#define TS2_I2C_ENUM_REMOTE_ACCE_15 0x0537
340
341
342/* page 0x06 */
343/* reserved */
344
345
346/* page 0x07 */
347/* voltage, current, temperature, power (puck only), pwm (puck only) */
348#define TS2_I2C_ID 0x0700
349#define TS2_I2C_ID_AIRBOARD_0 0x2c
350#define TS2_I2C_FLAGS_0 0x0701
351#define TS2_I2C_FLAGS_0_PUCK_PRIORITY (1<<0)
352#define TS2_I2C_FLAGS_1 0x0702
353#define TS2_I2C_FLAGS_2 0x0703
354#define TS2_I2C_FLAGS_2_A2A_CONNECT 0x80
355#define TS2_I2C_FLAGS_2_A2A_ATTEMPT 0x40
356#define TS2_I2C_FLAGS_2_BATTERY_DETECT 0x20
357#define TS2_I2C_FLAGS_2_WIRED_CHARGE 0x10
358#define TS2_I2C_FLAGS_2_PUCK_CHARGE 0x08
359#define TS2_I2C_FLAGS_2_WIRED 0x04
360#define TS2_I2C_FLAGS_2_PUCK 0x02
361#define TS2_I2C_FLAGS_2_PUCK_DETECT 0x01
362#define TS2_I2C_V_LOCAL 0x0704
363#define TS2_I2C_I_LOCAL 0x0705
364#define TS2_I2C_T_LOCAL 0x0706
365#define TS2_I2C_P_LOCAL 0x0707 /* puck only */
366#define TS2_I2C_V_REMOTE 0x0708
367#define TS2_I2C_I_REMOTE 0x0709
368#define TS2_I2C_T_REMOTE 0x070a
369#define TS2_I2C_P_REMOTE 0x070b /* puck only */
370#define TS2_I2C_PWM 0x070c /* puck only */
371#define TS2_I2C_PERIOD 0x070d /* puck only */
372
373/* config */
374#define TS2_I2C_TX_POWER_V1 0x0740
375#define TS2_I2C_TX_POWER_V2 0x0741
376
377/* puck only config */
378#define TS2_I2C_PWM_PERIOD 0x0780
379#define TS2_I2C_PWM_DUTY_ENUM 0x0781
380#define TS2_I2C_PWM_DUTY_MIN_RUN 0x0782
381#define TS2_I2C_PWM_DUTY_MIN_BOOST 0x0783
382#define TS2_I2C_PWM_DEADTIME 0x0784
383#define TS2_I2C_PWM_EFFICIENCY_OFFSET 0x0785
384#define TS2_I2C_PWM_EFFICIENCY_SCALE 0x0786
385
386/* airboard only */
387#define TS2_I2C_V_OFFSET 0x07c0
388#define TS2_I2C_WAKEUP_PERIOD 0x07c1
389#define TS2_I2C_CURRENT_ADJ_FOR_V1_SLOPE 0x07c2
390#define TS2_I2C_CURRENT_ADJ_FOR_V1_OFFSET 0x07c3
391#define TS2_I2C_VOLTAGE_ADJ_FOR_V1_SLOPE 0x07c4
392#define TS2_I2C_VOLTAGE_ADJ_FOR_V1_OFFSET 0x07c5
393
394/* misc registers */
395#define TS2_I2C_COMMAND 0x1000
396#define TS2_I2C_COMMAND_RESET_HOST 0x01
397#define TS2_I2C_COMMAND_CLEAR_BTN_SEQ_RESET_FLAG 0x02
398
399#define TS2_I2C_COMMAND_COMM_CONNECT 0x10
400#define TS2_I2C_COMMAND_COMM_DISCONNECT 0x11
401#define TS2_I2C_COMMAND_REENUMERATE 0x12
402
403#define TS2_I2C_COMMAND_FRAM_CHECKSUM_1400_READ 0x20
404#define TS2_I2C_COMMAND_FRAM_CHECKSUM_READ_1 0x21
405#define TS2_I2C_COMMAND_FRAM_CHECKSUM_READ_2 0x22
406
407#define TS2_I2C_COMMAND_MEM_READ_BYTE 0x80
408#define TS2_I2C_COMMAND_MEM_READ_CHAWMP 0x81
409#define TS2_I2C_COMMAND_MEM_WRITE_BYTE 0x82
410#define TS2_I2C_COMMAND_MEM_WRITE_CHAWMP 0x83
411#define TS2_I2C_COMMAND_PMIC_READ 0x84
412#define TS2_I2C_COMMAND_PMIC_WRITE 0x85
413#define TS2_I2C_COMMAND_SP_READ 0x86
414#define TS2_I2C_COMMAND_SP_INDIRECT_READ 0x87
415#define TS2_I2C_COMMAND_ADDR_MSB 0x1001
416#define TS2_I2C_COMMAND_ADDR_LSB 0x1002
417#define TS2_I2C_COMMAND_DATA_MSB 0x1003
418#define TS2_I2C_COMMAND_DATA_LSB 0x1004
419
420#define TS2_I2C_DEBUG_TRACE_DATA_RESERVED_1 0x101e /* reserved 1 */
421#define TS2_I2C_DEBUG_TRACE_DATA_RESERVED_2 0x101f /* reserved 2 */
422#define TS2_I2C_DEBUG_TRACE_DATA 0x1020 /* side-effect */
423
424#define A6_REG_TS2_I2C_INT_MASK_0 0
425#define A6_REG_TS2_I2C_INT_MASK_1 1
426#define A6_REG_TS2_I2C_INT_MASK_2 2
427#define A6_REG_TS2_I2C_INT_MASK_3 3
428#define A6_REG_TS2_I2C_INT_STATUS_0 4
429#define A6_REG_TS2_I2C_INT_STATUS_1 5
430#define A6_REG_TS2_I2C_INT_STATUS_2 6
431#define A6_REG_TS2_I2C_INT_STATUS_3 7
432#define A6_REG_TS2_I2C_BAT_STATUS 8
433#define A6_REG_TS2_I2C_BAT_RARC 9
434#define A6_REG_TS2_I2C_BAT_RSRC 10
435#define A6_REG_TS2_I2C_BAT_AVG_CUR_LSB_MSB 11
436#define A6_REG_TS2_I2C_BAT_TEMP_LSB_MSB 12
437#define A6_REG_TS2_I2C_BAT_VOLT_LSB_MSB 13
438#define A6_REG_TS2_I2C_BAT_CUR_LSB_MSB 14
439#define A6_REG_TS2_I2C_BAT_COULOMB_LSB_MSB 15
440// #define A6_REG_TS2_I2C_BAT_AS 16 // two entries? TODO
441#define A6_REG_TS2_I2C_BAT_FULL_LSB_MSB 17
442#define A6_REG_TS2_I2C_BAT_FULL40_LSB_MSB 18
443#define A6_REG_TS2_I2C_BAT_RSNSP 19
444#define A6_REG_TS2_I2C_BAT_ROMID_0 20
445#define A6_REG_TS2_I2C_BAT_COMMAND_STATUS 21
446#define A6_REG_TS2_I2C_BAT_TEMP_LOW_LSB_MSB 22
447#define A6_REG_TS2_I2C_BAT_TEMP_HIGH_LSB_MSB 23
448#define A6_REG_TS2_I2C_BAT_VOLT_LOW_LSB_MSB 24
449#define A6_REG_TS2_I2C_BAT_RARC_CRIT 25
450#define A6_REG_TS2_I2C_BAT_RARC_LOW_2 26
451#define A6_REG_TS2_I2C_BAT_RARC_LOW_1 27
452#define A6_REG_TS2_I2C_BAT_RAAC_MSB 28
453#define A6_REG_TS2_I2C_ID 29
454#define A6_REG_TS2_I2C_FLAGS_0 30
455#define A6_REG_TS2_I2C_FLAGS_2 31
456#define A6_REG_VERSION 32
457#define A6_REG_TS2_I2C_V_OFFSET 33
458#define A6_REG_TS2_I2C_WAKEUP_PERIOD 34
459#define A6_REG_TS2_I2C_COMMAND 35
460#define A6_REG_REMOTE_VERSION 36
461#define A6_REG_ACCESSORY_DATA_0 37
462#define A6_REG_ACCESSORY_DATA_1 38
463#define A6_REG_ACCESSORY_DATA_2 39
464#define A6_REG_ACCESSORY_DATA_3 40
465#define A6_REG_ACCESSORY_DATA_4 41
466#define A6_REG_ACCESSORY_DATA_5 42
467#define A6_REG_ACCESSORY_DATA_6 43
468#define A6_REG_ACCESSORY_DATA_7 44
469#define A6_REG_ACCESSORY_DATA_8 45
470#define A6_REG_ACCESSORY_DATA_9 46
471#define A6_REG_ACCESSORY_DATA_10 47
472#define A6_REG_ACCESSORY_DATA_11 48
473#define A6_REG_ACCESSORY_DATA_12 49
474#define A6_REG_REMOTE_ACCESSORY_DATA_0 50
475#define A6_REG_REMOTE_ACCESSORY_DATA_1 51
476#define A6_REG_REMOTE_ACCESSORY_DATA_2 52
477#define A6_REG_REMOTE_ACCESSORY_DATA_3 53
478#define A6_REG_REMOTE_ACCESSORY_DATA_4 54
479#define A6_REG_REMOTE_ACCESSORY_DATA_5 55
480#define A6_REG_REMOTE_ACCESSORY_DATA_6 56
481#define A6_REG_REMOTE_ACCESSORY_DATA_7 57
482#define A6_REG_REMOTE_ACCESSORY_DATA_8 58
483#define A6_REG_REMOTE_ACCESSORY_DATA_9 59
484#define A6_REG_REMOTE_ACCESSORY_DATA_10 60
485#define A6_REG_REMOTE_ACCESSORY_DATA_11 61
486#define A6_REG_REMOTE_ACCESSORY_DATA_12 62
487#define A6_REG_TS2_I2C_COMM_STATUS 63
488#define A6_REG_TS2_I2C_COMM_TXDATA_RXDATA 64
489#define A6_REG_TS2_I2C_BAT_SACR_LSB_MSB 65
490#define A6_REG_TS2_I2C_BAT_ASL 66
491// #define A6_REG_TS2_I2C_BAT_AS 67 // two entries? TODO
492#define A6_REG_TS2_I2C_BAT_FAC_LSB_MSB 68
493#define A6_REG_MAX_POWER_AVAILABLE 69
494#define A6_REG_TS2_I2C_ENUM_REMOTE_STRUCT_VER 70
495#define A6_REG_ACCESSORY_DATA_13 71
496#define A6_REG_ACCESSORY_DATA_14 72
497#define A6_REG_ACCESSORY_DATA_15 73
498#define A6_REG_REMOTE_ACCESSORY_DATA_13 74
499#define A6_REG_REMOTE_ACCESSORY_DATA_14 75
500#define A6_REG_REMOTE_ACCESSORY_DATA_15 76
501#define A6_REG_TS2_I2C_ENUM_MIN_PWM 77
502#define A6_REG_ACCESSORY_DATA_COMBO 78
503#define A6_REG_REMOTE_ACCESSORY_DATA_COMBO 79
504#define A6_REG_TS2_I2C_COMMAND_ADDR_LSB_MSB 80
505#define A6_REG_TS2_I2C_COMMAND_DATA_LSB_MSB 81
506#define A6_REG_REMOTE_MFGRID_V1 82
507#define A6_REG_REMOTE_MFGRID_V2 83
508#define A6_REG_REMOTE_PRODUCTID_V1 84
509#define A6_REG_REMOTE_PRODUCTID_V2 85
510#define A6_REG_REMOTE_SERNO_V1 86
511#define A6_REG_REMOTE_SERNO_V2 87
512#define A6_REG_LOCAL_MFGRID 88
513#define A6_REG_LOCAL_PRODUCTID 89
514#define A6_REG_LOCAL_SERNO 90
515
516
517#define RSENSE_DEFAULT 20;
518#define FORCE_WAKE_TIMER_EXPIRY (HZ/20)
519
520#define a6_wait_event_ex(wq, condition) \
521do { \
522 if (condition) \
523 break; \
524 do { \
525 DEFINE_WAIT(__wait); \
526 \
527 for (;;) { \
528 prepare_to_wait_exclusive(&wq, &__wait, \
529 TASK_UNINTERRUPTIBLE); \
530 if (condition) \
531 break; \
532 schedule(); \
533 } \
534 finish_wait(&wq, &__wait); \
535 } while (0); \
536} while (0)
537
538
539enum {
540 DEVICE_BUSY_BIT = 0,
541 IS_OPENED,
542 IS_INITIALIZED_BIT,
543 BOOTLOAD_ACTIVE_BIT,
544 FORCE_WAKE_ACTIVE_BIT,
545 READ_ACTIVE_BIT,
546 WRITE_ACTIVE_BIT,
547 A2A_CONNECTED,
548 EXTRACT_INITIATED,
549 // capabilities
550 CAP_PERIODIC_WAKE,
551#ifdef A6_PQ
552 STARTING_AID_TASK,
553 KILLING_AID_TASK,
554 IS_QUIESCED,
555#endif
556 IS_SUSPENDED,
557 INT_PENDING,
558 SIZE_FLAGS
559};
560
561struct a6_device_state {
562 struct i2c_client *i2c_dev;
563 struct a6_platform_data *plat_data;
564 struct file_operations fops;
565 struct miscdevice mdev;
566
567 struct mutex dev_mutex;
568 unsigned int timestamping;
569
570 struct timer_list a6_force_wake_timer;
571 struct work_struct a6_force_wake_work;
572 struct mutex a6_force_wake_mutex;
573
574 wait_queue_head_t dev_busyq;
575 struct work_struct a6_irq_work;
576
577 int32_t cpufreq_hold_flag;
578 struct workqueue_struct* ka6d_workqueue;
579 struct workqueue_struct* ka6d_fw_workqueue;
580
581 uint32_t cached_rsense_val: 16;
582 uint32_t busy_count: 8;
583 DECLARE_BITMAP(flags, SIZE_FLAGS);
584
585#ifdef A6_PQ
586 struct completion aq_enq_complete;
587 struct completion aid_exit_complete;
588 struct mutex aq_mutex;
589 struct list_head aq_head;
590 struct task_struct* ai_dispatch_task;
591#ifdef A6_DEBUG
592 uint32_t dbgflg_kill_raid: 1;
593
594 uint8_t debug_restart_aid;
595 uint8_t debug_flush_aiq;
596 uint8_t debug_unused_01;
597 uint8_t debug_unused_02;
598#endif
599#endif
600
601 int cpufreq_hold;
602
603 // pmem extract
604 struct file_operations pmem_fops;
605 struct miscdevice pmem_mdev;
606 char pmem_dev_name[16];
607
608 char *a2a_rd_buf, *a2a_wr_buf;
609 char *a2a_rp, *a2a_wp;
610
611 enum chg_type otg_chg_type;
612 struct delayed_work charge_work;
613 struct delayed_work init_connected_ps_work;
614 int stop_heartbeat;
615 int last_percent;
616
617 struct switch_dev *dock_switch;
618};
619
620struct a6_device_state *batt_state;
621
622#ifdef A6_PQ
623int32_t a6_start_ai_dispatch_task(struct a6_device_state* state);
624int32_t a6_stop_ai_dispatch_task(struct a6_device_state* state);
625int32_t flush_a6_action_items(struct a6_device_state* state);
626#endif
627
628static ssize_t a6_generic_show(struct device *dev, struct device_attribute *dev_attr, char *buf);
629static ssize_t a6_generic_store(struct device *dev, struct device_attribute *dev_attr, const char *buf,
630 size_t count);
631
632typedef int32_t (*format_show_fn)(const struct a6_device_state* state, const uint8_t* val,
633 uint8_t* fmt_buffer, uint32_t size_buffer);
634typedef int32_t (*format_store_fn)(const struct a6_device_state* state, const uint8_t* fmt_buffer,
635 uint8_t* val, uint32_t size_buffer);
636
637int32_t format_current(const struct a6_device_state* state, const uint8_t* val,
638 uint8_t* fmt_buffer, uint32_t size_buffer);
639int32_t format_voltage(const struct a6_device_state* state, const uint8_t* val,
640 uint8_t* fmt_buffer, uint32_t size_buffer);
641int32_t r_format_voltage(const struct a6_device_state* state, const uint8_t* fmt_buffer,
642 uint8_t* val, uint32_t size_buffer);
643int32_t format_rawcoulomb(const struct a6_device_state* state, const uint8_t* val,
644 uint8_t* fmt_buffer, uint32_t size_buffer);
645int32_t format_coulomb(const struct a6_device_state* state, const uint8_t* val,
646 uint8_t* fmt_buffer, uint32_t size_buffer);
647int32_t format_age(const struct a6_device_state* state, const uint8_t* val,
648 uint8_t* fmt_buffer, uint32_t size_buffer);
649int32_t format_fullx(const struct a6_device_state* state, const uint8_t* val,
650 uint8_t* fmt_buffer, uint32_t size_buffer);
651int32_t format_temp(const struct a6_device_state* state, const uint8_t* val,
652 uint8_t* fmt_buffer, uint32_t size_buffer);
653int32_t r_format_temp(const struct a6_device_state* state, const uint8_t* fmt_buffer,
654 uint8_t* val, uint32_t size_buffer);
655int32_t format_status(const struct a6_device_state* state, const uint8_t* val,
656 uint8_t* fmt_buffer, uint32_t size_buffer);
657int32_t format_rsense(const struct a6_device_state* state, const uint8_t* val,
658 uint8_t* fmt_buffer, uint32_t size_buffer);
659int32_t format_charge_source_status(const struct a6_device_state* state, const uint8_t* val,
660 uint8_t* fmt_buffer, uint32_t size_buffer);
661int32_t format_version(const struct a6_device_state* state, const uint8_t* val,
662 uint8_t* fmt_buffer, uint32_t size_buffer);
663int32_t format_v_offset(const struct a6_device_state* state, const uint8_t* val,
664 uint8_t* fmt_buffer, uint32_t size_buffer);
665int32_t format_command(const struct a6_device_state* state, const uint8_t* val,
666 uint8_t* fmt_buffer, uint32_t size_buffer);
667int32_t format_accessory(const struct a6_device_state* state, const uint8_t* val,
668 uint8_t* fmt_buffer, uint32_t size_buffer);
669int32_t format_comm_status(const struct a6_device_state* state, const uint8_t* val,
670 uint8_t* fmt_buffer, uint32_t size_buffer);
671int32_t format_raw_unsigned(const struct a6_device_state* state, const uint8_t* val,
672 uint8_t* fmt_buffer, uint32_t size_buffer);
673int32_t format_max_power_available(const struct a6_device_state* state, const uint8_t* val,
674 uint8_t* fmt_buffer, uint32_t size_buffer);
675int32_t format_accessory_combo(const struct a6_device_state* state, const uint8_t* val,
676 uint8_t* fmt_buffer, uint32_t size_buffer);
677int32_t format_u16_hex(const struct a6_device_state* state, const uint8_t* val,
678 uint8_t* fmt_buffer, uint32_t size_buffer);
679int32_t format_serno_v1(const struct a6_device_state* state, const uint8_t* val,
680 uint8_t* fmt_buffer, uint32_t size_buffer);
681int32_t format_serno_v2(const struct a6_device_state* state, const uint8_t* val,
682 uint8_t* fmt_buffer, uint32_t size_buffer);
683
684static ssize_t a6_diag_show(struct device *dev, struct device_attribute *dev_attr, char *buf);
685static ssize_t a6_diag_store(struct device *dev, struct device_attribute *dev_attr, const char *buf,
686 size_t count);
687static ssize_t a6_val_cksum_show(struct device *dev, struct device_attribute *attr, char *buf);
688
689static void a6_dock_update_state(struct a6_device_state *state);
690
691static void a6_update_connected_ps(void);
692
693void a6_force_wake_timer_callback(ulong data);
694/*
695 Note: 16-bit accesses comprising an LSB, MSB register pair must be specified in LSB:MSB order
696 in the corresponding a6_register_desc struct. This is because an a6-fw constraint
697 restricts 16-bit value accesses to MSB-leading only. The a6_i2c_read_reg and the
698 a6_i2c_write_reg functions take the LSB:MSB definition in the a6_register_desc struct
699 and re-orders the i2c txn to read in MSB:LSB order.
700*/
701struct a6_register_desc {
702#define id_size 20
703
704 const char* debug_name;
705 struct device_attribute dev_attr;
706 format_show_fn format;
707 format_store_fn r_format;
708 uint16_t id[id_size];
709 uint32_t num_ids: 5;
710 uint32_t ro: 1;
711} a6_register_desc_arr[] = {
712 /* interrupt control registers */
713 [0] = { .debug_name = "TS2_I2C_INT_MASK_0",
714 {{.name = "int_mask0", .mode = S_IRUGO | S_IWUGO},
715 .show = a6_generic_show, .store = a6_generic_store},
716 .id = {TS2_I2C_INT_MASK_0}, .num_ids = 1, .ro = 0},
717 [1] = { .debug_name = "TS2_I2C_INT_MASK_1",
718 {{.name = "int_mask1", .mode = S_IRUGO | S_IWUGO},
719 .show = a6_generic_show, .store = a6_generic_store},
720 .id = {TS2_I2C_INT_MASK_1}, .num_ids = 1, .ro = 0},
721 [2] = { .debug_name = "TS2_I2C_INT_MASK_2",
722 {{.name = "int_mask2", .mode = S_IRUGO | S_IWUGO},
723 .show = a6_generic_show, .store = a6_generic_store},
724 .id = {TS2_I2C_INT_MASK_2}, .num_ids = 1, .ro = 0},
725 [3] = { .debug_name = "TS2_I2C_INT_MASK_3",
726 {{.name = "int_mask3", .mode = S_IRUGO | S_IWUGO},
727 .show = a6_generic_show, .store = a6_generic_store},
728 .id = {TS2_I2C_INT_MASK_3}, .num_ids = 1, .ro = 0},
729 [4] = { .debug_name = "TS2_I2C_INT_STATUS_0",
730 {{.name = "int_status0", .mode = S_IRUGO | S_IWUGO},
731 .show = a6_generic_show, .store = a6_generic_store},
732 .id = {TS2_I2C_INT_STATUS_0}, .num_ids = 1, .ro = 0},
733 [5] = { .debug_name = "TS2_I2C_INT_STATUS_1",
734 {{.name = "int_status1", .mode = S_IRUGO | S_IWUGO},
735 .show = a6_generic_show, .store = a6_generic_store},
736 .id = {TS2_I2C_INT_STATUS_1}, .num_ids = 1, .ro = 0},
737 [6] = { .debug_name = "TS2_I2C_INT_STATUS_2",
738 {{.name = "int_status2", .mode = S_IRUGO | S_IWUGO},
739 .show = a6_generic_show, .store = a6_generic_store},
740 .id = {TS2_I2C_INT_STATUS_2}, .num_ids = 1, .ro = 0},
741 [7] = { .debug_name = "TS2_I2C_INT_STATUS_3",
742 {{.name = "int_status3", .mode = S_IRUGO | S_IWUGO},
743 .show = a6_generic_show, .store = a6_generic_store},
744 .id = {TS2_I2C_INT_STATUS_3}, .num_ids = 1, .ro = 0},
745
746 /* battery control registers */
747 [8] = { .debug_name = "TS2_I2C_BAT_STATUS",
748 {{.name = "status", .mode = S_IRUGO},
749 .show = a6_generic_show, .store = NULL},
750 .format = format_status,
751 .id = {TS2_I2C_BAT_STATUS}, .num_ids = 1, .ro = 1},
752 [9] = { .debug_name = "TS2_I2C_BAT_RARC",
753 {{.name = "getpercent", .mode = S_IRUGO},
754 .show = a6_generic_show, .store = NULL},
755 .id = {TS2_I2C_BAT_RARC}, .num_ids = 1, .ro = 1},
756 [10] = { .debug_name = "TS2_I2C_BAT_RSRC",
757 {{.name = "rsrc", .mode = S_IRUGO},
758 .show = a6_generic_show, .store = NULL},
759 .id = {TS2_I2C_BAT_RSRC}, .num_ids = 1, .ro = 1},
760 [11] = { .debug_name = "TS2_I2C_BAT_AVG_CUR_LSB_MSB",
761 {{.name = "getavgcurrent", .mode = S_IRUGO},
762 .show = a6_generic_show, .store = NULL},
763 .format = format_current,
764 .id = {TS2_I2C_BAT_AVG_CUR_LSB, TS2_I2C_BAT_AVG_CUR_MSB},
765 .num_ids = 2, .ro = 1},
766 [12] = { .debug_name = "TS2_I2C_BAT_TEMP_LSB_MSB",
767 {{.name = "gettemp", .mode = S_IRUGO},
768 .show = a6_generic_show, .store = NULL},
769 .format = format_temp,
770 .id = {TS2_I2C_BAT_TEMP_LSB, TS2_I2C_BAT_TEMP_MSB},
771 .num_ids = 2, .ro = 1},
772 [13] = { .debug_name = "TS2_I2C_BAT_VOLT_LSB_MSB",
773 {{.name = "getvoltage", .mode = S_IRUGO},
774 .show = a6_generic_show, .store = NULL},
775 .format = format_voltage,
776 .id = {TS2_I2C_BAT_VOLT_LSB, TS2_I2C_BAT_VOLT_MSB},
777 .num_ids = 2, .ro = 1},
778 [14] = { .debug_name = "TS2_I2C_BAT_CUR_LSB_MSB",
779 {{.name = "getcurrent", .mode = S_IRUGO},
780 .show = a6_generic_show, .store = NULL},
781 .format = format_current,
782 .id = {TS2_I2C_BAT_CUR_LSB, TS2_I2C_BAT_CUR_MSB},
783 .num_ids = 2, .ro = 1},
784 [15] = { .debug_name = "TS2_I2C_BAT_COULOMB_LSB_MSB",
785 {{.name = "getrawcoulomb", .mode = S_IRUGO},
786 .show = a6_generic_show, .store = NULL},
787 .format = format_rawcoulomb,
788 .id = {TS2_I2C_BAT_COULOMB_LSB, TS2_I2C_BAT_COULOMB_MSB},
789 .num_ids = 2, .ro = 1},
790 [16] = { .debug_name = "TS2_I2C_BAT_AS",
791 {{.name = "getage", .mode = S_IRUGO|S_IWUGO},
792 .show = a6_generic_show, .store = a6_generic_store},
793 .format = format_age,
794 .id = {TS2_I2C_BAT_AS}, .num_ids = 1, .ro = 0},
795 [17] = { .debug_name = "TS2_I2C_BAT_FULL_LSB_MSB",
796 {{.name = "getfull", .mode = S_IRUGO},
797 .show = a6_generic_show, .store = NULL},
798 .format = format_fullx,
799 .id = {TS2_I2C_BAT_FULL_LSB, TS2_I2C_BAT_FULL_MSB},
800 .num_ids = 2, .ro = 1},
801 [18] = {.debug_name = "TS2_I2C_BAT_FULL40_LSB_MSB",
802 {{.name = "getfull40", .mode = S_IRUGO},
803 .show = a6_generic_show, .store = NULL},
804 .format = format_fullx,
805 .id = {TS2_I2C_BAT_FULL40_LSB, TS2_I2C_BAT_FULL40_MSB},
806 .num_ids = 2, .ro = 1},
807 [19] = {.debug_name = "TS2_I2C_BAT_RSNSP",
808 {{.name = "getrsense", .mode = S_IRUGO},
809 .show = a6_generic_show, .store = NULL},
810 .format = format_rsense,
811 .id = {TS2_I2C_BAT_RSNSP}, .num_ids = 1, .ro = 1},
812
813 [20] = {.debug_name = "TS2_I2C_BAT_ROMID_0",
814 {{.name = "romid_0", .mode = S_IRUGO},
815 .show = a6_generic_show, .store = NULL},
816 .id = {TS2_I2C_BAT_ROMID_0}, .num_ids = 1, .ro = 1},
817
818 [21] = {.debug_name = "TS2_I2C_BAT_COMMAND_STATUS",
819 {{.name = "command_status", .mode = S_IRUGO|S_IWUGO},
820 .show = a6_generic_show, .store = a6_generic_store},
821 .id = {TS2_I2C_BAT_COMMAND_STATUS}, .num_ids = 1, .ro = 0},
822
823
824 [22] = {.debug_name = "TS2_I2C_BAT_TEMP_LOW_LSB_MSB",
825 {{.name = "temp_low", .mode = S_IRUGO|S_IWUGO},
826 .show = a6_generic_show, .store = a6_generic_store},
827 .format = format_temp,
828 .r_format = r_format_temp,
829 .id = {TS2_I2C_BAT_TEMP_LOW_LSB, TS2_I2C_BAT_TEMP_LOW_MSB},
830 .num_ids = 2, .ro = 0},
831 [23] = {.debug_name = "TS2_I2C_BAT_TEMP_HIGH_LSB_MSB",
832 {{.name = "temp_high", .mode = S_IRUGO|S_IWUGO},
833 .show = a6_generic_show, .store = a6_generic_store},
834 .format = format_temp,
835 .r_format = r_format_temp,
836 .id = {TS2_I2C_BAT_TEMP_HIGH_LSB, TS2_I2C_BAT_TEMP_HIGH_MSB},
837 .num_ids = 2, .ro = 0},
838 [24] = {.debug_name = "TS2_I2C_BAT_VOLT_LOW_LSB_MSB",
839 {{.name = "volt_low", .mode = S_IRUGO|S_IWUGO},
840 .show = a6_generic_show, .store = a6_generic_store},
841 .format = format_voltage,
842 .r_format = r_format_voltage,
843 .id = {TS2_I2C_BAT_VOLT_LOW_LSB, TS2_I2C_BAT_VOLT_LOW_MSB},
844 .num_ids = 2, .ro = 0},
845 [25] = {.debug_name = "TS2_I2C_BAT_RARC_CRIT",
846 {{.name = "rarc_crit", .mode = S_IRUGO|S_IWUGO},
847 .show = a6_generic_show, .store = a6_generic_store},
848 .id = {TS2_I2C_BAT_RARC_CRIT}, .num_ids = 1, .ro = 0},
849 [26] = {.debug_name = "TS2_I2C_BAT_RARC_LOW_2",
850 {{.name = "rarc_low_2", .mode = S_IRUGO|S_IWUGO},
851 .show = a6_generic_show, .store = a6_generic_store},
852 .id = {TS2_I2C_BAT_RARC_LOW_2}, .num_ids = 1, .ro = 0},
853 [27] = {.debug_name = "TS2_I2C_BAT_RARC_LOW_1",
854 {{.name = "rarc_low_1", .mode = S_IRUGO|S_IWUGO},
855 .show = a6_generic_show, .store = a6_generic_store},
856 .id = {TS2_I2C_BAT_RARC_LOW_1}, .num_ids = 1, .ro = 0},
857 [28] = {.debug_name = "TS2_I2C_BAT_RAAC_MSB",
858 {{.name = "getcoulomb", .mode = S_IRUGO|S_IWUGO},
859 .show = a6_generic_show, .store = a6_generic_store},
860 .format = format_coulomb,
861 .id = {TS2_I2C_BAT_RAAC_LSB, TS2_I2C_BAT_RAAC_MSB},
862 .num_ids = 2, .ro = 0},
863
864 /* puck registers */
865 [29] = {.debug_name = "TS2_I2C_ID",
866 {{.name = "id", .mode = S_IRUGO},
867 .show = a6_generic_show, .store = NULL},
868 .id = {TS2_I2C_ID}, .num_ids = 1, .ro = 1},
869 [30] = {.debug_name = "TS2_I2C_FLAGS_0",
870 {{.name = "puck_priority", .mode = S_IRUGO|S_IWUGO},
871 .show = a6_generic_show, .store = a6_generic_store},
872 .id = {TS2_I2C_FLAGS_0}, .num_ids = 1, .ro = 0},
873 [31] = {.debug_name = "TS2_I2C_FLAGS_2",
874 {{.name = "charger", .mode = S_IRUGO},
875 .show = a6_generic_show, .store = NULL},
876 .format = format_charge_source_status,
877 .id = {TS2_I2C_FLAGS_2}, .num_ids = 1, .ro = 1},
878
879 /* enumeration registers */
880 [32] = {.debug_name = "VERSION",
881 {{.name = "getversion", .mode = S_IRUGO},
882 .show = a6_generic_show, .store = NULL},
883 .format = format_version,
884 .id = { TS2_I2C_ENUM_MFGR_ID_LO, TS2_I2C_ENUM_MFGR_ID_HI,
885 TS2_I2C_ENUM_PRODUCT_TYPE_LO, TS2_I2C_ENUM_PRODUCT_TYPE_HI,
886 TS2_I2C_ENUM_SERNO_0, TS2_I2C_ENUM_SERNO_1,
887 TS2_I2C_ENUM_SERNO_2, TS2_I2C_ENUM_SERNO_3,
888 TS2_I2C_ENUM_SERNO_4, TS2_I2C_ENUM_SERNO_5,
889 TS2_I2C_ENUM_SERNO_6, TS2_I2C_ENUM_SERNO_7,
890 TS2_I2C_ENUM_ASSY_REV, TS2_I2C_ENUM_FW_VER_0,
891 TS2_I2C_ENUM_FW_VER_1, TS2_I2C_ENUM_FW_VER_2},
892 .num_ids = 16, .ro = 1},
893
894 /* puck registers */
895 [33] = {.debug_name = "TS2_I2C_V_OFFSET",
896 {{.name = "v_offset", .mode = S_IRUGO|S_IWUGO},
897 .show = a6_generic_show, .store = a6_generic_store},
898 .format = format_v_offset,
899 .id = {TS2_I2C_V_OFFSET}, .num_ids = 1, .ro = 0},
900
901 /* self-wake registers */
902 [34] = {.debug_name = "TS2_I2C_WAKEUP_PERIOD",
903 {{.name = "periodic_wake_bit_params", .mode = S_IRUGO|S_IWUGO},
904 .show = a6_generic_show, .store = a6_generic_store},
905 .id = {TS2_I2C_WAKEUP_PERIOD}, .num_ids = 1, .ro = 0},
906
907 /* command registers */
908 [35] = {.debug_name = "TS2_I2C_COMMAND",
909 {{.name = "command", .mode = S_IWUGO},
910 .show = NULL, .store = a6_generic_store},
911 .id = {TS2_I2C_COMMAND}, .num_ids = 1, .ro = 0},
912
913 /* remote enumeration registers */
914 [36] = {.debug_name = "REMOTE_VERSION",
915 {{.name = "getremoteversion", .mode = S_IRUGO},
916 .show = a6_generic_show, .store = NULL},
917 .format = format_version,
918 .id = { TS2_I2C_ENUM_REMOTE_MFGR_ID_LO, TS2_I2C_ENUM_REMOTE_MFGR_ID_HI,
919 TS2_I2C_ENUM_REMOTE_PRODUCT_TYPE_LO, TS2_I2C_ENUM_REMOTE_PRODUCT_TYPE_HI,
920 TS2_I2C_ENUM_REMOTE_SERNO_0, TS2_I2C_ENUM_REMOTE_SERNO_1,
921 TS2_I2C_ENUM_REMOTE_SERNO_2, TS2_I2C_ENUM_REMOTE_SERNO_3,
922 TS2_I2C_ENUM_REMOTE_SERNO_4, TS2_I2C_ENUM_REMOTE_SERNO_5,
923 TS2_I2C_ENUM_REMOTE_SERNO_6, TS2_I2C_ENUM_REMOTE_SERNO_7,
924 TS2_I2C_ENUM_REMOTE_ASSY_REV, TS2_I2C_ENUM_REMOTE_FW_VER_0,
925 TS2_I2C_ENUM_REMOTE_FW_VER_1, TS2_I2C_ENUM_REMOTE_FW_VER_2},
926 .num_ids = 16, .ro = 1},
927
928 /* accessory data registers */
929 [37] = {.debug_name = "ACCESSORY_DATA_0",
930 {{.name = "acc_data_0", .mode = S_IRUGO|S_IWUGO},
931 .show = a6_generic_show, .store = a6_generic_store},
932 .format = format_accessory,
933 .id = { TS2_I2C_ENUM_ACCE_0}, .num_ids = 1, .ro = 0},
934
935 [38] = {.debug_name = "ACCESSORY_DATA_1",
936 {{.name = "acc_data_1", .mode = S_IRUGO|S_IWUGO},
937 .show = a6_generic_show, .store = a6_generic_store},
938 .format = format_accessory,
939 .id = { TS2_I2C_ENUM_ACCE_1}, .num_ids = 1, .ro = 0},
940
941 [39] = {.debug_name = "ACCESSORY_DATA_2",
942 {{.name = "acc_data_2", .mode = S_IRUGO|S_IWUGO},
943 .show = a6_generic_show, .store = a6_generic_store},
944 .format = format_accessory,
945 .id = { TS2_I2C_ENUM_ACCE_2}, .num_ids = 1, .ro = 0},
946
947 [40] = {.debug_name = "ACCESSORY_DATA_3",
948 {{.name = "acc_data_3", .mode = S_IRUGO|S_IWUGO},
949 .show = a6_generic_show, .store = a6_generic_store},
950 .format = format_accessory,
951 .id = { TS2_I2C_ENUM_ACCE_3}, .num_ids = 1, .ro = 0},
952
953 [41] = {.debug_name = "ACCESSORY_DATA_4",
954 {{.name = "acc_data_4", .mode = S_IRUGO|S_IWUGO},
955 .show = a6_generic_show, .store = a6_generic_store},
956 .format = format_accessory,
957 .id = { TS2_I2C_ENUM_ACCE_4}, .num_ids = 1, .ro = 0},
958
959 [42] = {.debug_name = "ACCESSORY_DATA_5",
960 {{.name = "acc_data_5", .mode = S_IRUGO|S_IWUGO},
961 .show = a6_generic_show, .store = a6_generic_store},
962 .format = format_accessory,
963 .id = { TS2_I2C_ENUM_ACCE_5}, .num_ids = 1, .ro = 0},
964
965 [43] = {.debug_name = "ACCESSORY_DATA_6",
966 {{.name = "acc_data_6", .mode = S_IRUGO|S_IWUGO},
967 .show = a6_generic_show, .store = a6_generic_store},
968 .format = format_accessory,
969 .id = { TS2_I2C_ENUM_ACCE_6}, .num_ids = 1, .ro = 0},
970
971 [44] = {.debug_name = "ACCESSORY_DATA_7",
972 {{.name = "acc_data_7", .mode = S_IRUGO|S_IWUGO},
973 .show = a6_generic_show, .store = a6_generic_store},
974 .format = format_accessory,
975 .id = { TS2_I2C_ENUM_ACCE_7}, .num_ids = 1, .ro = 0},
976
977 [45] = {.debug_name = "ACCESSORY_DATA_8",
978 {{.name = "acc_data_8", .mode = S_IRUGO|S_IWUGO},
979 .show = a6_generic_show, .store = a6_generic_store},
980 .format = format_accessory,
981 .id = { TS2_I2C_ENUM_ACCE_8}, .num_ids = 1, .ro = 0},
982
983 [46] = {.debug_name = "ACCESSORY_DATA_9",
984 {{.name = "acc_data_9", .mode = S_IRUGO|S_IWUGO},
985 .show = a6_generic_show, .store = a6_generic_store},
986 .format = format_accessory,
987 .id = { TS2_I2C_ENUM_ACCE_9}, .num_ids = 1, .ro = 0},
988
989 [47] = {.debug_name = "ACCESSORY_DATA_10",
990 {{.name = "acc_data_10", .mode = S_IRUGO|S_IWUGO},
991 .show = a6_generic_show, .store = a6_generic_store},
992 .format = format_accessory,
993 .id = { TS2_I2C_ENUM_ACCE_10}, .num_ids = 1, .ro = 0},
994
995 [48] = {.debug_name = "ACCESSORY_DATA_11",
996 {{.name = "acc_data_11", .mode = S_IRUGO|S_IWUGO},
997 .show = a6_generic_show, .store = a6_generic_store},
998 .format = format_accessory,
999 .id = { TS2_I2C_ENUM_ACCE_11}, .num_ids = 1, .ro = 0},
1000
1001 [49] = {.debug_name = "ACCESSORY_DATA_12",
1002 {{.name = "acc_data_12", .mode = S_IRUGO|S_IWUGO},
1003 .show = a6_generic_show, .store = a6_generic_store},
1004 .format = format_accessory,
1005 .id = { TS2_I2C_ENUM_ACCE_12}, .num_ids = 1, .ro = 0},
1006
1007 /* remote accessory data registers */
1008 [50] = {.debug_name = "REMOTE_ACCESSORY_DATA_0",
1009 {{.name = "remote_acc_data_0", .mode = S_IRUGO},
1010 .show = a6_generic_show, .store = NULL},
1011 .format = format_accessory,
1012 .id = { TS2_I2C_ENUM_REMOTE_ACCE_0}, .num_ids = 1, .ro = 1},
1013
1014 [51] = {.debug_name = "REMOTE_ACCESSORY_DATA_1",
1015 {{.name = "remote_acc_data_1", .mode = S_IRUGO},
1016 .show = a6_generic_show, .store = NULL},
1017 .format = format_accessory,
1018 .id = { TS2_I2C_ENUM_REMOTE_ACCE_1}, .num_ids = 1, .ro = 1},
1019
1020 [52] = {.debug_name = "REMOTE_ACCESSORY_DATA_2",
1021 {{.name = "remote_acc_data_2", .mode = S_IRUGO},
1022 .show = a6_generic_show, .store = NULL},
1023 .format = format_accessory,
1024 .id = { TS2_I2C_ENUM_REMOTE_ACCE_2}, .num_ids = 1, .ro = 1},
1025
1026 [53] = {.debug_name = "REMOTE_ACCESSORY_DATA_3",
1027 {{.name = "remote_acc_data_3", .mode = S_IRUGO},
1028 .show = a6_generic_show, .store = NULL},
1029 .format = format_accessory,
1030 .id = { TS2_I2C_ENUM_REMOTE_ACCE_3}, .num_ids = 1, .ro = 1},
1031
1032 [54] = {.debug_name = "REMOTE_ACCESSORY_DATA_4",
1033 {{.name = "remote_acc_data_4", .mode = S_IRUGO},
1034 .show = a6_generic_show, .store = NULL},
1035 .format = format_accessory,
1036 .id = { TS2_I2C_ENUM_REMOTE_ACCE_4}, .num_ids = 1, .ro = 1},
1037
1038 [55] = {.debug_name = "REMOTE_ACCESSORY_DATA_5",
1039 {{.name = "remote_acc_data_5", .mode = S_IRUGO},
1040 .show = a6_generic_show, .store = NULL},
1041 .format = format_accessory,
1042 .id = { TS2_I2C_ENUM_REMOTE_ACCE_5}, .num_ids = 1, .ro = 1},
1043
1044 [56] = {.debug_name = "REMOTE_ACCESSORY_DATA_6",
1045 {{.name = "remote_acc_data_6", .mode = S_IRUGO},
1046 .show = a6_generic_show, .store = NULL},
1047 .format = format_accessory,
1048 .id = { TS2_I2C_ENUM_REMOTE_ACCE_6}, .num_ids = 1, .ro = 1},
1049
1050 [57] = {.debug_name = "REMOTE_ACCESSORY_DATA_7",
1051 {{.name = "remote_acc_data_7", .mode = S_IRUGO},
1052 .show = a6_generic_show, .store = NULL},
1053 .format = format_accessory,
1054 .id = { TS2_I2C_ENUM_REMOTE_ACCE_7}, .num_ids = 1, .ro = 1},
1055
1056 [58] = {.debug_name = "REMOTE_ACCESSORY_DATA_8",
1057 {{.name = "remote_acc_data_8", .mode = S_IRUGO},
1058 .show = a6_generic_show, .store = NULL},
1059 .format = format_accessory,
1060 .id = { TS2_I2C_ENUM_REMOTE_ACCE_8}, .num_ids = 1, .ro = 1},
1061
1062 [59] = {.debug_name = "REMOTE_ACCESSORY_DATA_9",
1063 {{.name = "remote_acc_data_9", .mode = S_IRUGO},
1064 .show = a6_generic_show, .store = NULL},
1065 .format = format_accessory,
1066 .id = { TS2_I2C_ENUM_REMOTE_ACCE_9}, .num_ids = 1, .ro = 1},
1067
1068 [60] = {.debug_name = "REMOTE_ACCESSORY_DATA_10",
1069 {{.name = "remote_acc_data_10", .mode = S_IRUGO},
1070 .show = a6_generic_show, .store = NULL},
1071 .format = format_accessory,
1072 .id = { TS2_I2C_ENUM_REMOTE_ACCE_10}, .num_ids = 1, .ro = 1},
1073
1074 [61] = {.debug_name = "REMOTE_ACCESSORY_DATA_11",
1075 {{.name = "remote_acc_data_11", .mode = S_IRUGO},
1076 .show = a6_generic_show, .store = NULL},
1077 .format = format_accessory,
1078 .id = { TS2_I2C_ENUM_REMOTE_ACCE_11}, .num_ids = 1, .ro = 1},
1079
1080 [62] = {.debug_name = "REMOTE_ACCESSORY_DATA_12",
1081 {{.name = "remote_acc_data_12", .mode = S_IRUGO},
1082 .show = a6_generic_show, .store = NULL},
1083 .format = format_accessory,
1084 .id = { TS2_I2C_ENUM_REMOTE_ACCE_12}, .num_ids = 1, .ro = 1},
1085
1086 [63] = {.debug_name = "TS2_I2C_COMM_STATUS",
1087 {{.name = "get_comm_status", .mode = S_IRUGO},
1088 .show = a6_generic_show, .store = NULL},
1089 .format = format_comm_status,
1090 .id = {TS2_I2C_COMM_STATUS}, .num_ids = 1, .ro = 1},
1091
1092 [64] = {.debug_name = "TS2_I2C_COMM_TXDATA_RXDATA",
1093 {{.name = "comm_txdata_rx_data", .mode = S_IRUGO|S_IWUGO},
1094 .show = a6_generic_show, .store = a6_generic_store},
1095 .format = format_comm_status,
1096 .id = {TS2_I2C_COMM_TXDATA_RXDATA}, .num_ids = 1, .ro = 0},
1097
1098 [65] = { .debug_name = "TS2_I2C_BAT_SACR_LSB_MSB",
1099 {{.name = "getsacr", .mode = S_IRUGO},
1100 .show = a6_generic_show, .store = NULL},
1101 .format = format_rawcoulomb,
1102 .id = {TS2_I2C_BAT_SACR_LSB, TS2_I2C_BAT_SACR_MSB},
1103 .num_ids = 2, .ro = 0},
1104
1105 [66] = { .debug_name = "TS2_I2C_BAT_ASL",
1106 {{.name = "getasl", .mode = S_IRUGO},
1107 .show = a6_generic_show, .store = NULL},
1108 .format = format_raw_unsigned,
1109 .id = {TS2_I2C_BAT_ASL}, .num_ids = 1, .ro = 0},
1110
1111 [67] = { .debug_name = "TS2_I2C_BAT_AS",
1112 {{.name = "getrawas", .mode = S_IRUGO},
1113 .show = a6_generic_show, .store = NULL},
1114 .format = format_raw_unsigned,
1115 .id = {TS2_I2C_BAT_AS}, .num_ids = 1, .ro = 0},
1116
1117 [68] = { .debug_name = "TS2_I2C_BAT_FAC_LSB_MSB",
1118 {{.name = "getfac", .mode = S_IRUGO},
1119 .show = a6_generic_show, .store = NULL},
1120 .format = format_rawcoulomb,
1121 .id = {TS2_I2C_BAT_FAC_LSB, TS2_I2C_BAT_FAC_MSB},
1122 .num_ids = 2, .ro = 0},
1123
1124 [69] = {.debug_name = "MAX_POWER_AVAILABLE",
1125 {{.name = "getmaxpoweravail", .mode = S_IRUGO},
1126 .show = a6_generic_show, .store = NULL},
1127 .format = format_max_power_available,
1128 .id = { TS2_I2C_ENUM_REMOTE_VNODE_MAX_LO, TS2_I2C_ENUM_REMOTE_VNODE_MAX_HI,
1129 TS2_I2C_ENUM_REMOTE_INODE_MAX_LO, TS2_I2C_ENUM_REMOTE_INODE_MAX_HI,
1130 TS2_I2C_ENUM_REMOTE_POWER_MAX},
1131 .num_ids = 5, .ro = 1},
1132
1133 [70] = {.debug_name = "TS2_I2C_ENUM_REMOTE_STRUCT_VER",
1134 {{.name = "remote_struct_ver", .mode = S_IRUGO},
1135 .show = a6_generic_show, .store = NULL},
1136 .id = {TS2_I2C_ENUM_REMOTE_STRUCT_VER}, .num_ids = 1, .ro = 1},
1137
1138 [71] = {.debug_name = "ACCESSORY_DATA_13",
1139 {{.name = "acc_data_13", .mode = S_IRUGO|S_IWUGO},
1140 .show = a6_generic_show, .store = a6_generic_store},
1141 .format = format_accessory,
1142 .id = { TS2_I2C_ENUM_ACCE_13}, .num_ids = 1, .ro = 0},
1143
1144 [72] = {.debug_name = "ACCESSORY_DATA_14",
1145 {{.name = "acc_data_14", .mode = S_IRUGO|S_IWUGO},
1146 .show = a6_generic_show, .store = a6_generic_store},
1147 .format = format_accessory,
1148 .id = { TS2_I2C_ENUM_ACCE_14}, .num_ids = 1, .ro = 0},
1149
1150 [73] = {.debug_name = "ACCESSORY_DATA_15",
1151 {{.name = "acc_data_15", .mode = S_IRUGO|S_IWUGO},
1152 .show = a6_generic_show, .store = a6_generic_store},
1153 .format = format_accessory,
1154 .id = { TS2_I2C_ENUM_ACCE_15}, .num_ids = 1, .ro = 0},
1155
1156 [74] = {.debug_name = "REMOTE_ACCESSORY_DATA_13",
1157 {{.name = "remote_acc_data_13", .mode = S_IRUGO},
1158 .show = a6_generic_show, .store = NULL},
1159 .format = format_accessory,
1160 .id = { TS2_I2C_ENUM_REMOTE_ACCE_13}, .num_ids = 1, .ro = 1},
1161
1162 [75] = {.debug_name = "REMOTE_ACCESSORY_DATA_14",
1163 {{.name = "remote_acc_data_14", .mode = S_IRUGO},
1164 .show = a6_generic_show, .store = NULL},
1165 .format = format_accessory,
1166 .id = { TS2_I2C_ENUM_REMOTE_ACCE_14}, .num_ids = 1, .ro = 1},
1167
1168 [76] = {.debug_name = "REMOTE_ACCESSORY_DATA_15",
1169 {{.name = "remote_acc_data_15", .mode = S_IRUGO},
1170 .show = a6_generic_show, .store = NULL},
1171 .format = format_accessory,
1172 .id = { TS2_I2C_ENUM_REMOTE_ACCE_15}, .num_ids = 1, .ro = 1},
1173
1174 [77] = {.debug_name = "TS2_I2C_ENUM_MIN_PWM",
1175 {{.name = "min_pwm", .mode = S_IRUGO|S_IWUGO},
1176 .show = a6_generic_show, .store = a6_generic_store},
1177 .id = { TS2_I2C_ENUM_MIN_PWM}, .num_ids = 1, .ro = 0},
1178
1179 [78] = {.debug_name = "ACCESSORY_DATA_COMBO",
1180 {{.name = "acc_data_combo", .mode = S_IRUGO|S_IWUGO},
1181 .show = a6_generic_show, .store = a6_generic_store},
1182 .format = format_accessory_combo,
1183 .id = { TS2_I2C_ENUM_ACCE_0, TS2_I2C_ENUM_ACCE_1, TS2_I2C_ENUM_ACCE_2,
1184 TS2_I2C_ENUM_ACCE_3, TS2_I2C_ENUM_ACCE_4, TS2_I2C_ENUM_ACCE_5,
1185 TS2_I2C_ENUM_ACCE_6, TS2_I2C_ENUM_ACCE_7, TS2_I2C_ENUM_ACCE_8,
1186 TS2_I2C_ENUM_ACCE_9, TS2_I2C_ENUM_ACCE_10, TS2_I2C_ENUM_ACCE_11,
1187 TS2_I2C_ENUM_ACCE_12, TS2_I2C_ENUM_ACCE_13, TS2_I2C_ENUM_ACCE_14,
1188 TS2_I2C_ENUM_ACCE_15},
1189 .num_ids = 16, .ro = 0},
1190
1191 [79] = {.debug_name = "REMOTE_ACCESSORY_DATA_COMBO",
1192 {{.name = "remote_acc_data_combo", .mode = S_IRUGO},
1193 .show = a6_generic_show, .store = NULL},
1194 .format = format_accessory_combo,
1195 .id = { TS2_I2C_ENUM_REMOTE_ACCE_0, TS2_I2C_ENUM_REMOTE_ACCE_1,
1196 TS2_I2C_ENUM_REMOTE_ACCE_2, TS2_I2C_ENUM_REMOTE_ACCE_3,
1197 TS2_I2C_ENUM_REMOTE_ACCE_4, TS2_I2C_ENUM_REMOTE_ACCE_5,
1198 TS2_I2C_ENUM_REMOTE_ACCE_6, TS2_I2C_ENUM_REMOTE_ACCE_7,
1199 TS2_I2C_ENUM_REMOTE_ACCE_8, TS2_I2C_ENUM_REMOTE_ACCE_9,
1200 TS2_I2C_ENUM_REMOTE_ACCE_10, TS2_I2C_ENUM_REMOTE_ACCE_11,
1201 TS2_I2C_ENUM_REMOTE_ACCE_12, TS2_I2C_ENUM_REMOTE_ACCE_13,
1202 TS2_I2C_ENUM_REMOTE_ACCE_14, TS2_I2C_ENUM_REMOTE_ACCE_15},
1203 .num_ids = 16, .ro = 1},
1204
1205 [80] = {.debug_name = "TS2_I2C_COMMAND_ADDR_LSB_MSB",
1206 {{.name = "command_addr", .mode = S_IRUGO|S_IWUGO},
1207 .show = a6_generic_show, .store = a6_generic_store},
1208 .id = {TS2_I2C_COMMAND_ADDR_LSB, TS2_I2C_COMMAND_ADDR_MSB},
1209 .format = format_u16_hex,
1210 .num_ids = 2, .ro = 0},
1211 [81] = {.debug_name = "TS2_I2C_COMMAND_DATA_LSB_MSB",
1212 {{.name = "command_data", .mode = S_IRUGO|S_IWUGO},
1213 .show = a6_generic_show, .store = a6_generic_store},
1214 .id = {TS2_I2C_COMMAND_DATA_LSB, TS2_I2C_COMMAND_DATA_MSB},
1215 .format = format_u16_hex,
1216 .num_ids = 2, .ro = 0},
1217
1218 [82] = {.debug_name = "REMOTE_MFGRID_V1",
1219 {{.name = "remote_mfgrid_v1", .mode = S_IRUGO},
1220 .show = a6_generic_show, .store = NULL},
1221 .format = format_u16_hex,
1222 .id = { TS2_I2C_ENUM_REMOTE_MFGR_ID_LO_V1,
1223 TS2_I2C_ENUM_REMOTE_MFGR_ID_HI_V1},
1224 .num_ids = 2, .ro = 1},
1225 [83] = {.debug_name = "REMOTE_MFGRID_V2",
1226 {{.name = "remote_mfgrid_v2", .mode = S_IRUGO},
1227 .show = a6_generic_show, .store = NULL},
1228 .format = format_u16_hex,
1229 .id = { TS2_I2C_ENUM_REMOTE_MFGR_ID_LO,
1230 TS2_I2C_ENUM_REMOTE_MFGR_ID_HI},
1231 .num_ids = 2, .ro = 1},
1232 [84] = {.debug_name = "REMOTE_PRODUCTID_V1",
1233 {{.name = "remote_productid_v1", .mode = S_IRUGO},
1234 .show = a6_generic_show, .store = NULL},
1235 .format = format_u16_hex,
1236 .id = { TS2_I2C_ENUM_REMOTE_PRODUCT_TYPE_LO_V1,
1237 TS2_I2C_ENUM_REMOTE_PRODUCT_TYPE_HI_V1},
1238 .num_ids = 2, .ro = 1},
1239 [85] = {.debug_name = "REMOTE_PRODUCTID_V2",
1240 {{.name = "remote_productid_v2", .mode = S_IRUGO},
1241 .show = a6_generic_show, .store = NULL},
1242 .format = format_u16_hex,
1243 .id = { TS2_I2C_ENUM_REMOTE_PRODUCT_TYPE_LO,
1244 TS2_I2C_ENUM_REMOTE_PRODUCT_TYPE_HI},
1245 .num_ids = 2, .ro = 1},
1246 [86] = {.debug_name = "REMOTE_SERNO_V1",
1247 {{.name = "remote_serno_v1", .mode = S_IRUGO},
1248 .show = a6_generic_show, .store = NULL},
1249 .format = format_serno_v1,
1250 .id = { TS2_I2C_ENUM_REMOTE_SERNO_0, TS2_I2C_ENUM_REMOTE_SERNO_1,
1251 TS2_I2C_ENUM_REMOTE_SERNO_2, TS2_I2C_ENUM_REMOTE_SERNO_3,
1252 TS2_I2C_ENUM_REMOTE_SERNO_4, TS2_I2C_ENUM_REMOTE_SERNO_5},
1253 .num_ids = 6, .ro = 1},
1254 [87] = {.debug_name = "REMOTE_SERNO_V2",
1255 {{.name = "remote_serno_v2", .mode = S_IRUGO},
1256 .show = a6_generic_show, .store = NULL},
1257 .format = format_serno_v2,
1258 .id = { TS2_I2C_ENUM_REMOTE_SERNO_0, TS2_I2C_ENUM_REMOTE_SERNO_1,
1259 TS2_I2C_ENUM_REMOTE_SERNO_2, TS2_I2C_ENUM_REMOTE_SERNO_3,
1260 TS2_I2C_ENUM_REMOTE_SERNO_4, TS2_I2C_ENUM_REMOTE_SERNO_5,
1261 TS2_I2C_ENUM_REMOTE_SERNO_6, TS2_I2C_ENUM_REMOTE_SERNO_7},
1262 .num_ids = 8, .ro = 1},
1263 [88] = {.debug_name = "LOCAL_MFGRID",
1264 {{.name = "local_mfgrid", .mode = S_IRUGO},
1265 .show = a6_generic_show, .store = NULL},
1266 .format = format_u16_hex,
1267 .id = { TS2_I2C_ENUM_MFGR_ID_LO, TS2_I2C_ENUM_MFGR_ID_HI},
1268 .num_ids = 2, .ro = 1},
1269 [89] = {.debug_name = "LOCAL_PRODUCTID",
1270 {{.name = "local_productid", .mode = S_IRUGO},
1271 .show = a6_generic_show, .store = NULL},
1272 .format = format_u16_hex,
1273 .id = { TS2_I2C_ENUM_PRODUCT_TYPE_LO, TS2_I2C_ENUM_PRODUCT_TYPE_HI},
1274 .num_ids = 2, .ro = 1},
1275 [90] = {.debug_name = "LOCAL_SERNO",
1276 {{.name = "local_serno", .mode = S_IRUGO},
1277 .show = a6_generic_show, .store = NULL},
1278 .format = format_serno_v2,
1279 .id = { TS2_I2C_ENUM_SERNO_0, TS2_I2C_ENUM_SERNO_1,
1280 TS2_I2C_ENUM_SERNO_2, TS2_I2C_ENUM_SERNO_3,
1281 TS2_I2C_ENUM_SERNO_4, TS2_I2C_ENUM_SERNO_5,
1282 TS2_I2C_ENUM_SERNO_6, TS2_I2C_ENUM_SERNO_7},
1283 .num_ids = 8, .ro = 1},
1284};
1285
1286
1287struct device_attribute custom_devattr[] = {
1288 {{.name = "a6_diag", .mode = S_IRUGO | S_IWUGO},
1289 .show = a6_diag_show, .store = a6_diag_store},
1290 {{.name = "validate_cksum", .mode = S_IRUGO},
1291 .show = a6_val_cksum_show, .store = NULL},
1292};
1293
1294static enum power_supply_property a6_fish_battery_properties[] = {
1295 POWER_SUPPLY_PROP_STATUS,
1296 POWER_SUPPLY_PROP_HEALTH,
1297 POWER_SUPPLY_PROP_PRESENT,
1298 POWER_SUPPLY_PROP_TECHNOLOGY,
1299 POWER_SUPPLY_PROP_CAPACITY,
1300 POWER_SUPPLY_PROP_CURRENT_NOW,
1301 POWER_SUPPLY_PROP_VOLTAGE_NOW,
1302 POWER_SUPPLY_PROP_TEMP,
1303 POWER_SUPPLY_PROP_CHARGE_FULL,
1304 POWER_SUPPLY_PROP_CHARGE_NOW,
1305};
1306
1307static enum power_supply_property a6_fish_power_properties[] = {
1308 POWER_SUPPLY_PROP_ONLINE,
1309};
1310
1311static char *supply_list[] = {
1312 "battery",
1313};
1314
1315static int a6_fish_power_get_property(struct power_supply *psy,
1316 enum power_supply_property psp,
1317 union power_supply_propval *val);
1318
1319static int a6_fish_battery_get_property(struct power_supply *psy,
1320 enum power_supply_property psp,
1321 union power_supply_propval *val);
1322
1323static struct power_supply a6_fish_power_supplies[] = {
1324 {
1325 .name = "battery",
1326 .type = POWER_SUPPLY_TYPE_BATTERY,
1327 .properties = a6_fish_battery_properties,
1328 .num_properties = ARRAY_SIZE(a6_fish_battery_properties),
1329 .get_property = a6_fish_battery_get_property,
1330 },
1331 {
1332 .name = "ac",
1333 .type = POWER_SUPPLY_TYPE_MAINS,
1334 .supplied_to = supply_list,
1335 .num_supplicants = ARRAY_SIZE(supply_list),
1336 .properties = a6_fish_power_properties,
1337 .num_properties = ARRAY_SIZE(a6_fish_power_properties),
1338 .get_property = a6_fish_power_get_property,
1339 },
1340 {
1341 .name = "usb",
1342 .type = POWER_SUPPLY_TYPE_USB,
1343 .supplied_to = supply_list,
1344 .num_supplicants = ARRAY_SIZE(supply_list),
1345 .properties = a6_fish_power_properties,
1346 .num_properties = ARRAY_SIZE(a6_fish_power_properties),
1347 .get_property = a6_fish_power_get_property,
1348 },
1349#ifdef CONFIG_A6_ENABLE_DOCK_PS
1350 {
1351 .name = "dock",
1352 .type = POWER_SUPPLY_TYPE_MAINS,
1353 .supplied_to = supply_list,
1354 .num_supplicants = ARRAY_SIZE(supply_list),
1355 .properties = a6_fish_power_properties,
1356 .num_properties = ARRAY_SIZE(a6_fish_power_properties),
1357 .get_property = a6_fish_power_get_property,
1358 },
1359#endif
1360};
1361
1362#ifdef A6_PQ
1363// a6 debugfs interface...
1364#ifdef A6_DEBUG
1365
1366
1367static int32_t a6_restart_aid_thread_fn(void* param)
1368{
1369 struct a6_device_state* state = param;
1370 int32_t rc = 0;
1371
1372 daemonize("dbg_aidrst_%s", state->plat_data->dev_name);
1373 while (!state->dbgflg_kill_raid) {
1374 // stop aid task
1375 rc = a6_stop_ai_dispatch_task(state);
1376 if (rc) {
1377 printk(KERN_ERR "%s: failed to stop ai_dispatch_task.\n", __func__);
1378 break;
1379 }
1380
1381 // re-start aid task
1382 rc = a6_start_ai_dispatch_task(state);
1383 if (rc) {
1384 printk(KERN_ERR "%s: failed to start ai_dispatch_task.\n", __func__);
1385 break;
1386 }
1387
1388 // sleep
1389 msleep(500);
1390 }
1391
1392 rc = mutex_lock_interruptible(&state->dev_mutex);
1393 if (rc) {
1394 printk(KERN_ERR "%s: mutex_lock_interruptible interrupted\n", __func__);
1395 return -ERESTARTSYS;
1396 }
1397 state->debug_restart_aid = 0;
1398 state->dbgflg_kill_raid = 0;
1399 mutex_unlock(&state->dev_mutex);
1400
1401 return rc;
1402}
1403
1404static int a6_test_restart_aid_set(void *data, u64 val)
1405{
1406 int32_t rc = 0;
1407 pid_t aiq_flush_pid = 0;
1408 struct a6_device_state* state = data;
1409 uint8_t in_val, curr_val;
1410
1411 in_val = val ? 1 : val;
1412 rc = mutex_lock_interruptible(&state->dev_mutex);
1413 if (rc) {
1414 printk(KERN_ERR "%s: mutex_lock_interruptible interrupted\n", __func__);
1415 return -ERESTARTSYS;
1416 }
1417 curr_val = state->debug_restart_aid;
1418
1419 // are we actually changing state?
1420 if (in_val ^ curr_val) {
1421 if (in_val) {
1422 // prev task still being killed or active: fail
1423 if (state->dbgflg_kill_raid || state->debug_restart_aid) {
1424 printk(KERN_ERR "%s: prev task still being killed or active: fail\n",
1425 __func__);
1426 goto err0;
1427 }
1428 // create ai dispatcher task...
1429 aiq_flush_pid = kernel_thread(a6_restart_aid_thread_fn, state, CLONE_KERNEL);
1430 ASSERT(aiq_flush_pid >= 0);
1431 state->debug_restart_aid = in_val;
1432 }
1433 else {
1434 // prev task still being killed or not active: fail
1435 if (state->dbgflg_kill_raid || !state->debug_restart_aid) {
1436 printk(KERN_ERR "%s: prev task still being killed or not active: fail\n",
1437 __func__);
1438 goto err0;
1439 }
1440 // intent to kill task; task resets state as part of teardown
1441 state->dbgflg_kill_raid = 1;
1442 }
1443 }
1444 mutex_unlock(&state->dev_mutex);
1445
1446
1447err0:
1448 return rc;
1449}
1450static int a6_test_restart_aid_get(void *data, u64 *val)
1451{
1452 struct a6_device_state* state = data;
1453
1454 *val = state->debug_restart_aid;
1455 return 0;
1456}
1457
1458DEFINE_SIMPLE_ATTRIBUTE(fops_a6_test_restart_aid, a6_test_restart_aid_get, a6_test_restart_aid_set, "%llu\n");
1459
1460static int32_t a6_create_debug_interface(struct a6_device_state* state)
1461{
1462 int32_t rc = 0;
1463 struct dentry *dentry_parent, *dentry_child;
1464
1465 dentry_parent = debugfs_create_dir("a6", 0);
1466 if (IS_ERR(dentry_parent)) {
1467 rc = PTR_ERR(dentry_parent);
1468 goto err0;
1469 }
1470
1471 dentry_child = debugfs_create_file("periodic_restart_aid", 0644,
1472 dentry_parent, state, &fops_a6_test_restart_aid);
1473 if (IS_ERR(dentry_child)) {
1474 rc = PTR_ERR(dentry_child);
1475 goto err0;
1476 }
1477
1478 return 0;
1479
1480err0:
1481 debugfs_remove_recursive(dentry_parent);
1482 return rc;
1483}
1484#endif
1485#endif // A6_PQ
1486
1487#ifdef A6_PQ
1488// a6 action item types
1489enum {
1490 AI_I2C_TYPE,
1491};
1492
1493struct a6_action_item {
1494 void* ai_payload;
1495 uint32_t ai_type: 4;
1496 uint32_t ai_complete:1;
1497 int32_t (*ai_do_action)(void* payload_param);
1498 int32_t* (*ai_ret_code)(void* payload_param);
1499 wait_queue_head_t ai_waitq;
1500 struct list_head list;
1501};
1502
1503/*
1504 enq_a6_action_item: q's action item and blocks till action completion...
1505*/
1506int32_t enq_a6_action_item(struct a6_device_state* state, struct a6_action_item* ai, bool enq_tail)
1507{
1508 int32_t rc = 0;
1509
1510 mutex_lock(&state->aq_mutex);
1511 if (true == enq_tail) {
1512 list_add_tail(&ai->list, &state->aq_head);
1513 }
1514 else {
1515 list_add(&ai->list, &state->aq_head);
1516 }
1517 mutex_unlock(&state->aq_mutex);
1518
1519 // signal the action_item dispatcher thread
1520 complete(&state->aq_enq_complete);
1521
1522 // ** wait for action_item to be processed
1523 a6_wait_event_ex(ai->ai_waitq, ai->ai_complete);
1524 rc = *ai->ai_ret_code(ai->ai_payload);
1525
1526 return rc;
1527}
1528
1529/*
1530 dq_a6_action_item: dq's head item from action item list...
1531*/
1532struct a6_action_item* dq_a6_action_item(struct a6_device_state* state)
1533{
1534 struct a6_action_item* ai = NULL;
1535
1536 mutex_lock(&state->aq_mutex);
1537 if (!list_empty(&state->aq_head)) {
1538 ai = list_first_entry(&state->aq_head, struct a6_action_item, list);
1539 list_del(state->aq_head.next);
1540 }
1541 mutex_unlock(&state->aq_mutex);
1542
1543 return ai;
1544}
1545
1546/*
1547 flush_a6_action_items: iterates action item list, dq's each item, marks it cancelled
1548 and complete and then wakes up the requestor...
1549*/
1550int32_t flush_a6_action_items(struct a6_device_state* state)
1551{
1552 int32_t rc = 0;
1553 struct a6_action_item* ai = NULL;
1554
1555 // lock list until all items removed
1556 mutex_lock(&state->aq_mutex);
1557 while (!list_empty(&state->aq_head)) {
1558 // get first entry...
1559 ai = list_first_entry(&state->aq_head, struct a6_action_item, list);
1560 // ... and remove from list
1561 list_del(state->aq_head.next);
1562 *ai->ai_ret_code(ai->ai_payload) = -ECANCELED;
1563 // set completion indicator
1564 ai->ai_complete = 1;
1565 // signal ai requestor
1566 wake_up(&ai->ai_waitq);
1567 }
1568 mutex_unlock(&state->aq_mutex);
1569
1570 return rc;
1571}
1572
1573
1574struct ai_i2c_payload {
1575 struct i2c_client* client;
1576 struct i2c_msg* msg;
1577 uint32_t num_msgs;
1578 int32_t rc;
1579};
1580
1581/*
1582 do_i2c_action_item: i2c-specific action implementation...
1583*/
1584int32_t do_i2c_action_item(void* payload_param)
1585{
1586 struct ai_i2c_payload* trf_data = (struct ai_i2c_payload*)payload_param;
1587
1588 trf_data->rc = i2c_transfer(trf_data->client->adapter, trf_data->msg, trf_data->num_msgs);
1589 udelay(700);
1590 if (trf_data->rc < 0) {
1591 printk(KERN_ERR "%s: err code: %d\n", __func__, trf_data->rc);
1592 goto err0;
1593 }
1594
1595 trf_data->rc = 0;
1596err0:
1597 return trf_data->rc;
1598}
1599
1600/*
1601 i2c_ret_code: i2c-specific ret-code reference retrieval...
1602*/
1603int32_t* i2c_ret_code(void* payload_param)
1604{
1605 struct ai_i2c_payload* trf_data = (struct ai_i2c_payload*)payload_param;
1606
1607 return (&trf_data->rc);
1608}
1609
1610/*
1611 q_a6_i2c_action_item: creates the action item structure and enq's it...
1612*/
1613int32_t q_a6_i2c_action_item(struct i2c_client* client, struct i2c_msg* msg, uint32_t num_msgs)
1614{
1615 int32_t ret = 0;
1616 struct ai_i2c_payload data = {
1617 .client = client,
1618 .msg = msg,
1619 .num_msgs = num_msgs,
1620 .rc = 0
1621 };
1622
1623 struct a6_action_item a6_i2c_ai = {
1624 .ai_payload = &data,
1625 .ai_type = AI_I2C_TYPE,
1626 .ai_complete = 0,
1627 .ai_do_action = do_i2c_action_item,
1628 .ai_ret_code = i2c_ret_code,
1629 .list = LIST_HEAD_INIT(a6_i2c_ai.list)
1630 };
1631
1632 init_waitqueue_head(&a6_i2c_ai.ai_waitq);
1633 ret = enq_a6_action_item(i2c_get_clientdata(client), &a6_i2c_ai, true/*enq tail*/);
1634
1635 return ret;
1636}
1637
1638/*
1639 ai_dispatch_thread_fn: function that handles ai processing in the aid task...
1640*/
1641int ai_dispatch_thread_fn(void* param)
1642{
1643 int32_t rc = 0;
1644 struct a6_action_item* ai;
1645 struct a6_device_state* state = param;
1646
1647 daemonize("aid_%s", state->plat_data->dev_name);
1648 do {
1649 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: about to wait for ai enq complete.\n", __func__);
1650 // wait for ai to be enq'd
1651 rc = wait_for_completion_interruptible(&state->aq_enq_complete);
1652 if (rc >= 0) {
1653 // check kill status: intent to kill?
1654 if (test_bit(KILLING_AID_TASK, state->flags)) {
1655 // remove all items from q
1656 flush_a6_action_items(state);
1657 // and signal killer before exiting stage...
1658 complete(&state->aid_exit_complete);
1659 break;
1660 }
1661
1662 ai = dq_a6_action_item(state);
1663 if (ai) {
1664 int32_t ret_val;
1665
1666 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: got ai.\n", __func__);
1667 // invoke ai-specific action
1668 ret_val = ai->ai_do_action(ai->ai_payload);
1669 if (ret_val) {
1670 printk(KERN_ERR "%s: ai_do_action failed.\n", __func__);
1671 }
1672
1673 // set completion indicator
1674 ai->ai_complete = 1;
1675 // signal ai requestor
1676 wake_up(&ai->ai_waitq);
1677 }
1678 else {
1679 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: no ai.\n", __func__);
1680 }
1681 }
1682 // wait interrupted by -ERESTARTSYS: let's exit
1683 else {
1684 printk(KERN_ERR "%s: wait for action_item enq interrupted.\n",
1685 __func__);
1686 // force a panic...
1687 BUG_ON(rc < 0);
1688 }
1689 } while(rc >= 0);
1690
1691 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "*** %s: exiting ai_dispatch_thread_fn.***\n", __func__);
1692
1693 return rc;
1694}
1695#endif // A6_PQ
1696
1697
1698int32_t __a6_i2c_read_reg(struct i2c_client* client, const uint16_t* ids, uint32_t num_ids, uint8_t* out)
1699{
1700 int32_t ret = 0, i;
1701 uint16_t swp_addr[num_ids];
1702 struct i2c_msg msg[num_ids*2], *msg_itr;
1703 struct a6_device_state* state = i2c_get_clientdata(client);
1704#ifdef A6_I2C_PROFILE
1705 ktime_t start, end;
1706#endif
1707
1708#ifdef A6_PQ
1709 if (test_bit(IS_QUIESCED, ((struct a6_device_state*)i2c_get_clientdata(client))->flags)) {
1710 ret = -ECANCELED;
1711 goto err0;
1712 }
1713#endif // A6_PQ
1714
1715 // force A6 wakeup...
1716 if (start_last_a6_activity) {
1717 long diff_time = (long)jiffies - (long)start_last_a6_activity;
1718 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: time since last activity: %ld ms\n",
1719 __func__, diff_time * 1000/HZ);
1720 }
1721 start_last_a6_activity = jiffies;
1722
1723 // prevent timer expiry during force_wake related action...
1724 del_timer(&state->a6_force_wake_timer);
1725
1726 mutex_lock(&state->a6_force_wake_mutex);
1727 // a6 external wake enabled?
1728 if (test_bit(CAP_PERIODIC_WAKE, state->flags)) {
1729 if (!test_bit(FORCE_WAKE_ACTIVE_BIT, state->flags)) {
1730 struct a6_wake_ops* wake_ops = (struct a6_wake_ops*)state->plat_data->wake_ops;
1731
1732 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR,
1733 "%s: disabling periodic_wake and switching to force_wake\n",
1734 __func__);
1735
1736 // periodic wake active: disable it and switch to force wake
1737 if (wake_ops->disable_periodic_wake) {
1738 wake_ops->disable_periodic_wake(wake_ops->data);
1739 }
1740 if (wake_ops->force_wake) {
1741 wake_ops->force_wake(wake_ops->data);
1742 }
1743
1744 set_bit(FORCE_WAKE_ACTIVE_BIT, state->flags);
1745 }
1746 }
1747 mutex_unlock(&state->a6_force_wake_mutex);
1748
1749#ifdef A6_I2C_PROFILE
1750 start = ktime_get();
1751#endif
1752 msg_itr = &msg[0];
1753 for (i = num_ids-1; i >= 0; i--) {
1754 msg_itr->addr = client->addr;
1755 msg_itr->flags = 0;
1756 msg_itr->len = sizeof(uint16_t);
1757 swp_addr[i] = ids[i] >> 8 | ids[i] << 8;
1758 msg_itr->buf = (uint8_t*)&swp_addr[i];
1759
1760 (msg_itr+1)->addr = client->addr;
1761 (msg_itr+1)->flags = I2C_M_RD;
1762 (msg_itr+1)->len = sizeof(uint8_t);
1763 (msg_itr+1)->buf = &out[i];
1764#ifdef CONFIG_A6_I2C_SINGLE_BYTE
1765#ifdef A6_PQ
1766 ret = q_a6_i2c_action_item(client, msg, 2);
1767#else
1768 ret = i2c_transfer(client->adapter, msg, 2);
1769#endif // A6_PQ
1770#endif
1771 msg_itr += 2;
1772 }
1773
1774
1775#ifndef CONFIG_A6_I2C_SINGLE_BYTE
1776#ifdef A6_PQ
1777 ret = q_a6_i2c_action_item(client, msg, num_ids*2);
1778#else
1779 ret = i2c_transfer(client->adapter, msg, num_ids*2);
1780#endif // A6_PQ
1781#endif
1782 //msleep(1);
1783#ifdef A6_I2C_PROFILE
1784 {
1785 end = ktime_get();
1786 printk(KERN_ERR "%s[0x%02x]: elpased time: %lld\n",
1787 __func__, client->addr, ktime_to_ns(ktime_sub(end, start)));
1788 }
1789#endif
1790 if (ret < 0) {
1791 printk(KERN_ERR "%s[0x%02x]: err code: %d\n", __func__, client->addr, ret);
1792 // reset the force_wake timer inedependent of i2c failure
1793 //goto err0;
1794 }
1795 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "ret val: 0x%x\n", *out);
1796
1797 if (test_bit(CAP_PERIODIC_WAKE, state->flags)) {
1798 // [re]start force-wake expiry timer
1799 mod_timer(&state->a6_force_wake_timer, jiffies+FORCE_WAKE_TIMER_EXPIRY);
1800 }
1801
1802err0:
1803 return ret;
1804}
1805
1806int32_t a6_i2c_read_reg(struct i2c_client* client, const uint16_t* ids, uint32_t num_ids, uint8_t* out)
1807{
1808 int32_t ret;
1809#ifdef A6_I2C_RETRY
1810 int32_t retry = 5;
1811#else
1812 int32_t retry = 0;
1813#endif
1814
1815 do {
1816 ret = __a6_i2c_read_reg(client, ids, num_ids, out);
1817 if (ret < 0) {
1818 printk("%s: a6 i2c transaction failed. %s...\n", __func__, retry ? "retry" : " ");
1819 msleep(30);
1820 }
1821 } while (0 != ret && retry-- > 0);
1822
1823 return ret;
1824}
1825
1826int32_t __a6_i2c_write_reg(struct i2c_client* client, const uint16_t* ids, uint32_t num_ids, const uint8_t* in)
1827{
1828 int32_t ret = 0, i;
1829 uint8_t i2c_buf[(2+1)*num_ids];
1830 struct i2c_msg msg[num_ids], *msg_itr;
1831 struct a6_device_state* state = i2c_get_clientdata(client);
1832
1833#ifdef A6_PQ
1834 if (test_bit(IS_QUIESCED, ((struct a6_device_state*)i2c_get_clientdata(client))->flags)) {
1835 ret = -ECANCELED;
1836 goto err0;
1837 }
1838#endif // A6_PQ
1839
1840 // force A6 wakeup...
1841 if (start_last_a6_activity) {
1842 long diff_time = (long)jiffies - (long)start_last_a6_activity;
1843 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: time since last activity: %ld ms\n",
1844 __func__, diff_time * 1000/HZ);
1845 }
1846 start_last_a6_activity = jiffies;
1847
1848 // prevent timer expiry during force_wake related action...
1849 del_timer(&state->a6_force_wake_timer);
1850
1851 mutex_lock(&state->a6_force_wake_mutex);
1852 if (test_bit(CAP_PERIODIC_WAKE, state->flags)) {
1853 if (!test_and_set_bit(FORCE_WAKE_ACTIVE_BIT, state->flags)) {
1854 struct a6_wake_ops* wake_ops = (struct a6_wake_ops*)state->plat_data->wake_ops;
1855
1856 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR,
1857 "%s: disabling periodic_wake and switching to force_wake\n",
1858 __func__);
1859
1860 // periodic wake active: disable it and switch to force wake
1861 if (wake_ops->disable_periodic_wake) {
1862 wake_ops->disable_periodic_wake(wake_ops->data);
1863 }
1864 if (wake_ops->force_wake) {
1865 wake_ops->force_wake(wake_ops->data);
1866 }
1867
1868 set_bit(FORCE_WAKE_ACTIVE_BIT, state->flags);
1869 }
1870 }
1871 mutex_unlock(&state->a6_force_wake_mutex);
1872
1873 msg_itr = &msg[0];
1874 for (i = num_ids-1; i >= 0; i--) {
1875 i2c_buf[(i*(2+1))+0] = (uint8_t)(ids[i] >> 8);
1876 i2c_buf[(i*(2+1))+1] = (uint8_t)(ids[i]);
1877 i2c_buf[(i*(2+1))+2] = in[i];
1878
1879 msg_itr->addr = client->addr;
1880 msg_itr->flags = 0;
1881 msg_itr->len = 2+1;
1882 msg_itr->buf = &i2c_buf[i*(2+1)];
1883#ifdef CONFIG_A6_I2C_SINGLE_BYTE_WRITE
1884#ifdef A6_PQ
1885 ret = q_a6_i2c_action_item(client, msg_itr, 1);
1886#else
1887 ret = i2c_transfer(client->adapter, msg_itr, 1);
1888#endif // A6_PQ
1889 udelay(700);
1890 if (ret < 0)
1891 break;
1892#endif
1893 msg_itr++;
1894 }
1895
1896#ifndef CONFIG_A6_I2C_SINGLE_BYTE_WRITE
1897#ifdef A6_PQ
1898 ret = q_a6_i2c_action_item(client, msg, num_ids);
1899#else
1900 ret = i2c_transfer(client->adapter, msg, num_ids);
1901#endif // A6_PQ
1902 //msleep(1);
1903#endif
1904 if (ret < 0) {
1905 printk(KERN_ERR "%s[0x%02x]: err code: %d\n", __func__, client->addr, ret);
1906 // reset the force_wake timer inedependent of i2c failure
1907 //goto err0;
1908 }
1909
1910 if (test_bit(CAP_PERIODIC_WAKE, state->flags)) {
1911 // [re]start force-wake expiry timer
1912 mod_timer(&state->a6_force_wake_timer, jiffies+FORCE_WAKE_TIMER_EXPIRY);
1913 }
1914
1915err0:
1916 return ret;
1917}
1918
1919int32_t a6_i2c_write_reg(struct i2c_client* client, const uint16_t* ids, uint32_t num_ids, const uint8_t* in)
1920{
1921 int32_t ret;
1922#ifdef A6_I2C_RETRY
1923 int32_t retry = 5;
1924#else
1925 int32_t retry = 0;
1926#endif
1927
1928 do {
1929 ret = __a6_i2c_write_reg(client, ids, num_ids, in);
1930 if (ret < 0) {
1931 printk("%s: a6 i2c transaction failed. %s...\n", __func__, retry ? "retry" : " ");
1932 msleep(30);
1933 }
1934 } while (0 != ret && retry-- > 0);
1935
1936 return ret;
1937}
1938
1939
1940uint8_t _convert_hex_char_to_decimal(uint8_t x)
1941{
1942 x -= '0';
1943 if (x > 9) {
1944 x = x - ('A' - ('9' + 1));
1945 if (x > 15) {
1946 x = x - ('a' - 'A');
1947 }
1948 }
1949
1950 return x;
1951}
1952
1953int32_t a6_init_state(struct i2c_client *client)
1954{
1955 int32_t ret = 0;
1956 struct a6_device_state* state = i2c_get_clientdata(client);
1957 struct a6_register_desc* reg_desc;
1958 uint8_t vals[id_size];
1959
1960 // early initialization of cached rsense to prevent un-initialized usage
1961 // due to early-boot i2c failures.
1962 state->cached_rsense_val = RSENSE_DEFAULT;
1963
1964 /* (1) enable external/internal wake, if required */
1965 /* periodic wake capability enabled? */
1966 if (test_bit(CAP_PERIODIC_WAKE, state->flags)) {
1967 struct a6_wake_ops* wake_ops = (struct a6_wake_ops*)state->plat_data->wake_ops;
1968
1969 // initialize timer used to force sleep after a force wake...
1970 setup_timer(&state->a6_force_wake_timer, a6_force_wake_timer_callback, (ulong)state);
1971
1972 /* enable external periodic wake? */
1973 if (wake_ops->enable_periodic_wake) {
1974 printk(KERN_ERR "%s: enabling external PMIC-generated A6 wake.\n", __func__);
1975
1976 wake_ops->enable_periodic_wake(wake_ops->data);
1977
1978 /* disable a6 internal-wake... */
1979 reg_desc = &a6_register_desc_arr[34];
1980 /* format wakeup parameters in register format */
1981 vals[0] = 0;
1982 ret = a6_i2c_write_reg(client, reg_desc->id, reg_desc->num_ids, vals);
1983 if (ret < 0) {
1984 goto err0;
1985 }
1986 }
1987 /* enable internal periodic wake? */
1988 else if (wake_ops->internal_wake_enable_state) {
1989 uint32_t wake_period = 0, wake_enable = 1;
1990
1991 printk(KERN_ERR "%s: enabling A6 internal wake.\n", __func__);
1992 /* default wake_period, if required */
1993 if (!wake_ops->internal_wake_period) {
1994 wake_period = 0x0;
1995 }
1996 else {
1997 wake_period = wake_ops->internal_wake_period(wake_ops->data);
1998 if (wake_period > 0x100) {
1999 wake_period = 0x100;
2000 }
2001 }
2002
2003 reg_desc = &a6_register_desc_arr[34];
2004
2005 if (!wake_period) {
2006 wake_enable = 0x0;
2007 }
2008
2009 // bit [4]: Enable sleep.
2010 // bit [3]: Enable automatic wakeup.
2011 // bits [2:0]: Sleep period.
2012 if (wake_period) {
2013 wake_period = find_last_bit((const unsigned long*)&wake_period, 32);
2014 wake_period--;
2015 }
2016 vals[0] = 0x10 | wake_enable << 3 | (wake_period & 0x07);
2017 printk(KERN_ERR "%s: TS2_I2C_WAKEUP_PERIOD = 0x%02x\n",
2018 __func__, vals[0]);
2019 ret = a6_i2c_write_reg(client, reg_desc->id, reg_desc->num_ids, vals);
2020 if (ret < 0) {
2021 goto err0;
2022 }
2023 }
2024 else {
2025 BUG();
2026 }
2027 }
2028 /* periodic wake capability not defined: force a6 awake using SBW_WAKEUP */
2029 else {
2030 printk(KERN_ERR "%s: permanently forcing A6 awake.\n", __func__);
2031 gpio_set_value(state->plat_data->sbw_wkup_gpio, 1);
2032 }
2033
2034 /* (2) cache rsense val */
2035 reg_desc = &a6_register_desc_arr[19];
2036
2037 memset(vals, 0, sizeof(vals));
2038 ret = a6_i2c_read_reg(client, reg_desc->id, reg_desc->num_ids, vals);
2039 if (ret < 0) {
2040 //goto err0;
2041 }
2042
2043 /* rsense == 0: invalid and results in default
2044 (logic compatibile with legacy w1 driver implementation) */
2045 if (vals[0]) {
2046 state->cached_rsense_val = 1000/vals[0];
2047 if (!state->cached_rsense_val) {
2048 state->cached_rsense_val = RSENSE_DEFAULT;
2049 }
2050 }
2051 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR,
2052 "%s: (cached) rsense value: %u\n", __func__, state->cached_rsense_val);
2053
2054 /* (3) enable irqs: MASK_A2A_CONNECT_CHANGE, MASK_FLAGS_CHANGE */
2055 reg_desc = &a6_register_desc_arr[3];
2056
2057 vals[0] = 0xf3;
2058 ret = a6_i2c_write_reg(client, reg_desc->id, reg_desc->num_ids, vals);
2059 if (ret < 0) {
2060 goto err0;
2061 }
2062
2063 /* (4) enable irqs:
2064 MASK_BAT_TEMP_HIGH, MASK_BAT_TEMP_LOW,
2065 MASK_BAT_VOLT_LOW, MASK_BAT_RARC_CRIT,
2066 MASK_BAT_RARC_LOW2, MASK_BAT_RARC_LOW1
2067 */
2068 reg_desc = &a6_register_desc_arr[2];
2069
2070 vals[0] = 0xc0;
2071 ret = a6_i2c_write_reg(client, reg_desc->id, reg_desc->num_ids, vals);
2072 if (ret < 0) {
2073 goto err0;
2074 }
2075 /* read version */
2076 reg_desc = &a6_register_desc_arr[32];
2077
2078 memset(vals, 0, sizeof(vals));
2079 ret = a6_i2c_read_reg(client, reg_desc->id, reg_desc->num_ids, vals);
2080 if (ret < 0) {
2081 printk(KERN_ERR "%s: error reading A6 version\n", __func__);
2082 }
2083 else {
2084 uint8_t buf[150];
2085
2086 reg_desc->format(state, vals, buf, sizeof(buf));
2087 printk(KERN_INFO "%s", buf);
2088 }
2089
2090 // if first init (device boot): clear all interrupt status regs because we might
2091 // have missed the level-triggered a6-irq during device boot and the user-space
2092 // components read a6 registers to set their initial state correctly...
2093 if (!test_bit(IS_INITIALIZED_BIT, state->flags)) {
2094 vals[0] = 0xff;
2095
2096 /* clear int_status3 */
2097 reg_desc = &a6_register_desc_arr[7];
2098 ret = a6_i2c_write_reg(state->i2c_dev, reg_desc->id, reg_desc->num_ids, vals);
2099 if (ret < 0) {
2100 printk(KERN_ERR "%s: error writing reg: %s, id: 0x%x\n",
2101 __func__, reg_desc->debug_name, reg_desc->id[0]);
2102 goto err0;
2103 }
2104
2105 /* clear int_status2 */
2106 reg_desc = &a6_register_desc_arr[6];
2107 ret = a6_i2c_write_reg(state->i2c_dev, reg_desc->id, reg_desc->num_ids, vals);
2108 if (ret < 0) {
2109 printk(KERN_ERR "%s: error writing reg: %s, id: 0x%x\n",
2110 __func__, reg_desc->debug_name, reg_desc->id[0]);
2111 goto err0;
2112 }
2113
2114 /* clear int_status1 */
2115 reg_desc = &a6_register_desc_arr[5];
2116 ret = a6_i2c_write_reg(state->i2c_dev, reg_desc->id, reg_desc->num_ids, vals);
2117 if (ret < 0) {
2118 printk(KERN_ERR "%s: error writing reg: %s, id: 0x%x\n",
2119 __func__, reg_desc->debug_name, reg_desc->id[0]);
2120 goto err0;
2121 }
2122 }
2123
2124 set_bit(IS_INITIALIZED_BIT, state->flags);
2125
2126err0:
2127 return ret;
2128}
2129
2130int32_t format_current(const struct a6_device_state* state, const uint8_t* val,
2131 uint8_t* fmt_buffer, uint32_t size_buffer)
2132{
2133 int32_t ret;
2134 int32_t conv_val = *(int16_t*)val; // (val[0]<<8) + val[1];
2135
2136 /* in uA */
2137 /* TODO: Bootie source code states:
2138 * Define R sense as 20 mOhms, as opposed as a variable and reading it
2139 * from the pack, not all packs have the correct R sense programmed
2140 */
2141 conv_val = (conv_val * 3125)/2/(int32_t)state->cached_rsense_val;
2142
2143 ret = scnprintf(fmt_buffer, size_buffer, "%d\n", conv_val);
2144 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR,
2145 "Current value (uA): %s\n", fmt_buffer);
2146 return ret;
2147}
2148
2149int32_t format_voltage(const struct a6_device_state* state, const uint8_t* val,
2150 uint8_t* fmt_buffer, uint32_t size_buffer)
2151{
2152 int32_t ret;
2153 int32_t conv_val = *(int16_t*)val; // (val[0]<<8) + val[1];
2154
2155 /* in uV -- 11-bit signed value, unit = 4880uV */
2156 conv_val = (conv_val>>5) * 4880;
2157 ret = scnprintf(fmt_buffer, size_buffer, "%d\n", conv_val);
2158 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "Voltage value (uV): %s\n",
2159 fmt_buffer);
2160 return ret;
2161}
2162
2163int32_t r_format_voltage(const struct a6_device_state* state, const uint8_t* fmt_buffer,
2164 uint8_t* val, uint32_t size_buffer)
2165{
2166 int32_t ret;
2167 uint32_t conv_val;
2168 const char *bufp;
2169 char *endp = NULL;
2170
2171 bufp = fmt_buffer;
2172 // let strtoul perform base determination (handles '0x' and '0' prefixes) ...
2173 conv_val = simple_strtoul(bufp, &endp, 0);
2174 /* in uV -- 11-bit signed value, unit = 4880uV */
2175 conv_val = (conv_val / 4880) << 5;
2176 // capped at 16 bits...
2177 if (conv_val >> 0x10) {
2178 ret = 0;
2179 goto err0;
2180 }
2181 ret = (uint32_t)endp - (uint32_t)bufp;
2182
2183 *(uint16_t*)val = conv_val;
2184
2185 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: ip: %s op: %d\n",
2186 __func__, fmt_buffer, conv_val);
2187
2188err0:
2189 return ret;
2190}
2191/**
2192 * Take the Accumulated Current Register (ACR), which is expressed in units of 6.25uVh
2193 * and convert to uAh.
2194 */
2195int32_t format_rawcoulomb(const struct a6_device_state* state, const uint8_t* val,
2196 uint8_t* fmt_buffer, uint32_t size_buffer)
2197{
2198 int32_t ret;
2199 int32_t conv_val = *(int16_t*)val; // (val[0]<<8) + val[1];
2200
2201 // in uAh
2202 conv_val = (conv_val * 6250) / (int32_t)state->cached_rsense_val;
2203 ret = scnprintf(fmt_buffer, size_buffer, "%d.%03d\n", conv_val/1000,
2204 ((conv_val >= 0)? conv_val : -conv_val) % 1000);
2205 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "Raw Coulomb value (uAh): %s\n",
2206 fmt_buffer);
2207 return ret;
2208}
2209
2210/**
2211 * Take the Remaining Active Absolute Capacity (RAAC) register, which is in
2212 * units of 1.6 mAh and convert to mAh
2213 */
2214int32_t format_coulomb(const struct a6_device_state* state, const uint8_t* val,
2215 uint8_t* fmt_buffer, uint32_t size_buffer)
2216{
2217 int32_t ret;
2218 int32_t conv_val = *(int16_t*)val;
2219
2220 // in mAh
2221 conv_val = (conv_val * 8) / 5;
2222 ret = scnprintf(fmt_buffer, size_buffer, "%d\n", conv_val);
2223 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "Coulomb value (mAh): %s\n",
2224 fmt_buffer);
2225 return ret;
2226}
2227
2228int32_t format_age(const struct a6_device_state* state, const uint8_t* val,
2229 uint8_t* fmt_buffer, uint32_t size_buffer)
2230{
2231 int32_t ret, conv_val;
2232
2233 // Age conversion factor, in .01 percent. Raw value 0x80 = 100%
2234 conv_val = (10000*val[0]) >> 7;
2235 ret = scnprintf(fmt_buffer, size_buffer, "%d.%02d\n",
2236 conv_val/100, conv_val%100);
2237 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "Battery life left (%%): %s\n",
2238 fmt_buffer);
2239 return ret;
2240}
2241
2242int32_t format_fullx(const struct a6_device_state* state, const uint8_t* val,
2243 uint8_t* fmt_buffer, uint32_t size_buffer)
2244{
2245 int32_t ret;
2246 int32_t conv_val = *(int16_t*)val; // (val[0]<<8) + val[1];
2247
2248 // Convert 6.25uVh to uAh
2249 conv_val = (conv_val * 6250) / state->cached_rsense_val;
2250 ret = scnprintf(fmt_buffer, size_buffer,
2251 "%d.%03d\n", conv_val/1000, conv_val%1000);
2252 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "Battery life left (uAh): %s\n",
2253 fmt_buffer);
2254 return ret;
2255}
2256
2257int32_t format_temp(const struct a6_device_state* state, const uint8_t* val,
2258 uint8_t* fmt_buffer, uint32_t size_buffer)
2259{
2260 int32_t ret;
2261 int conv_val = val[1]; /* Ignoring the fraction part */
2262
2263 // in C
2264 ret = snprintf(fmt_buffer, size_buffer, "%d\n", (int8_t)conv_val);
2265 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "Temperature (C): %s\n",
2266 fmt_buffer);
2267 return ret;
2268}
2269
2270int32_t format_command(const struct a6_device_state* state, const uint8_t* val,
2271 uint8_t* fmt_buffer, uint32_t size_buffer)
2272{
2273 int32_t ret;
2274 int conv_command_debug_code = val[0];
2275
2276 ret = snprintf(fmt_buffer, size_buffer, "%d\n", (int8_t)conv_command_debug_code);
2277 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "debug code(C): %s\n",
2278 fmt_buffer);
2279 return ret;
2280}
2281
2282int32_t format_accessory(const struct a6_device_state* state, const uint8_t* val,
2283 uint8_t* fmt_buffer, uint32_t size_buffer)
2284{
2285 int32_t ret;
2286
2287 ret = scnprintf(fmt_buffer, size_buffer, "%02X\n", val[0]);
2288 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "%s", fmt_buffer);
2289 return ret;
2290}
2291
2292int32_t format_comm_status(const struct a6_device_state* state, const uint8_t* val,
2293 uint8_t* fmt_buffer, uint32_t size_buffer)
2294{
2295 int32_t ret;
2296
2297 ret = scnprintf(fmt_buffer, size_buffer, "%02X\n", val[0]);
2298 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "%s", fmt_buffer);
2299 return ret;
2300}
2301
2302int32_t r_format_temp(const struct a6_device_state* state, const uint8_t* fmt_buffer,
2303 uint8_t* val, uint32_t size_buffer)
2304{
2305 int32_t ret;
2306 int32_t conv_val;
2307 const char *bufp;
2308 char *endp = NULL;
2309
2310 bufp = fmt_buffer;
2311 // let strtoul perform base determination (handles '0x' and '0' prefixes) ...
2312 conv_val = simple_strtol(bufp, &endp, 0);
2313 printk(KERN_ERR "conv_val : %d, hex: %x\n", conv_val, conv_val);
2314 // capped at 8 bits...
2315 if (conv_val < -128) {
2316 ret = 0;
2317 goto err0;
2318 }
2319 ret = (uint32_t)endp - (uint32_t)bufp;
2320
2321 /* Ignoring the fraction part */
2322 *(uint16_t*)val = (uint8_t)conv_val << 8;
2323
2324 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: ip: %s op: %d\n",
2325 __func__, fmt_buffer, conv_val<<8);
2326
2327err0:
2328 return ret;
2329}
2330
2331int32_t format_status(const struct a6_device_state* state, const uint8_t* val,
2332 uint8_t* fmt_buffer, uint32_t size_buffer)
2333{
2334 uint32_t conv_val = *val;
2335 int32_t count, i;
2336
2337 const char* status_bits[] = {
2338 NULL,
2339 "power-on-reset",
2340 "undervoltage",
2341 NULL,
2342 "learn",
2343 "standby-empty",
2344 "active-empty",
2345 "charge-termination"};
2346
2347 for (i = count = 0; i < sizeof(status_bits)/sizeof(status_bits[0]); i++) {
2348 if ((conv_val & (1 << i)) && status_bits[i] != NULL) {
2349 count += scnprintf(fmt_buffer + count, size_buffer-count, "%s\n", status_bits[i]);
2350 }
2351 }
2352 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR,
2353 "Battery status: %s\n", fmt_buffer);
2354
2355 return count;
2356}
2357
2358int32_t format_rsense(const struct a6_device_state* state, const uint8_t* val,
2359 uint8_t* fmt_buffer, uint32_t size_buffer)
2360{
2361 int32_t ret;
2362 uint32_t conv_val = *val;
2363
2364 ret = scnprintf(fmt_buffer, size_buffer, "%u\n", (!conv_val) ? conv_val : 1000/conv_val);
2365 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "rsense (ohm): %s\n",
2366 fmt_buffer);
2367 return ret;
2368}
2369
2370/**
2371 * Determine what, if any chargers are attached to the system. Only one
2372 * result will be returned, even if multiple chargers are detected.
2373 *
2374 * Output is a combination of:
2375 * 0x01 - Puck Detected
2376 * 0x02 - Puck Connected
2377 * 0x04 - Wired Power Detected
2378 * 0x08 - Puck Power Connected
2379 * 0x10 - Wired Power Connected
2380 * 0x20 - Battery Present
2381 *
2382 * Not all values are currently supported.
2383 */
2384int32_t format_charge_source_status(const struct a6_device_state* state, const uint8_t* val,
2385 uint8_t* fmt_buffer, uint32_t size_buffer)
2386{
2387 struct charge_source_status_map {
2388 uint32_t cs_mask;
2389 const char* cs_name;
2390 } cs_map[] = {
2391 [0] = {0x01, "Puck Detected"},
2392 [1] = {0x02, "Puck Connected"},
2393 [2] = {0x04, "Wired Power Detected"},
2394 [3] = {0x08, "Puck Power Connected"},
2395 [4] = {0x10, "Wired Power Connected"},
2396 [5] = {0x20, "Battery Present"},
2397 };
2398 uint32_t conv_val = *val, count = 0;
2399 int32_t i;
2400
2401 for(i = 0; i < sizeof(cs_map)/sizeof(cs_map[0]); i++) {
2402 if (conv_val & cs_map[i].cs_mask) {
2403 count += scnprintf(fmt_buffer + count, (size_buffer - 1) - count, "%s\n", cs_map[i].cs_name);
2404 }
2405 }
2406
2407 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR,
2408 "charge source status (formatted): %s\n", fmt_buffer);
2409
2410#ifdef A6_REPORT_CONNECTED_ONLY
2411 conv_val = 0;
2412 /* map charge source status to user-space values */
2413 /* TODO: differentiate wall charger from USB */
2414 if (val[0] & TS2_I2C_FLAGS_2_WIRED_CHARGE) conv_val |= 1;
2415 if (val[0] & TS2_I2C_FLAGS_2_PUCK_CHARGE) conv_val |= 4;
2416#endif
2417
2418 /* output register contents */
2419 count = scnprintf(fmt_buffer, size_buffer, "%u\n", conv_val);
2420 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR,
2421 "charge source status (literal): %s\n", fmt_buffer);
2422 return count;
2423}
2424
2425int32_t format_version(const struct a6_device_state* state, const uint8_t* val,
2426 uint8_t* fmt_buffer, uint32_t size_buffer)
2427{
2428 int32_t ret;
2429
2430 ret = scnprintf(fmt_buffer, size_buffer,
2431 "A6 Version: HW: %d, FW (M.m.B): %d.%d.%d, ManID: %d, ProdTyp: %d\n",
2432 val[12], val[15], val[14], val[13],
2433 *(int16_t*)&(val[0]), *(int16_t*)&(val[2]));
2434 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "%s", fmt_buffer);
2435 return ret;
2436}
2437
2438int32_t format_v_offset(const struct a6_device_state* state, const uint8_t* val,
2439 uint8_t* fmt_buffer, uint32_t size_buffer)
2440{
2441 int32_t ret;
2442 uint32_t conv_val = *val;
2443
2444 ret = scnprintf(fmt_buffer, size_buffer, "%u\n", conv_val);
2445 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "v_offset: %s\n", fmt_buffer);
2446 return ret;
2447}
2448
2449int32_t format_raw_unsigned(const struct a6_device_state* state, const uint8_t* val,
2450 uint8_t* fmt_buffer, uint32_t size_buffer)
2451{
2452 int32_t ret;
2453 uint32_t conv_val = *val;
2454
2455 ret = scnprintf(fmt_buffer, size_buffer, "%u\n", conv_val);
2456 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "raw_unsigned: %s\n", fmt_buffer);
2457 return ret;
2458}
2459
2460int32_t format_u16_hex(const struct a6_device_state* state, const uint8_t* val,
2461 uint8_t* fmt_buffer, uint32_t size_buffer)
2462{
2463 int32_t ret;
2464 uint16_t conv_val = *(uint16_t*)val;
2465
2466 ret = scnprintf(fmt_buffer, size_buffer, "0x%04hx\n", conv_val);
2467 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "u16_hex: %s\n", fmt_buffer);
2468 return ret;
2469}
2470
2471int32_t format_max_power_available(const struct a6_device_state* state, const uint8_t* val,
2472 uint8_t* fmt_buffer, uint32_t size_buffer)
2473{
2474 int32_t ret;
2475 uint32_t vnode_max_val = *(uint16_t*)val;
2476 uint32_t inode_max_val = *(uint16_t*)(val+2);
2477 uint32_t power_val = *(val+4);
2478 uint32_t conv_val;
2479
2480 conv_val = (vnode_max_val * inode_max_val * power_val)/2560;
2481 ret = scnprintf(fmt_buffer, size_buffer, "%u\n", conv_val);
2482 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "%s", fmt_buffer);
2483 return ret;
2484}
2485
2486int32_t format_accessory_combo(const struct a6_device_state* state, const uint8_t* val,
2487 uint8_t* fmt_buffer, uint32_t size_buffer)
2488{
2489 int32_t ret;
2490
2491 ret = scnprintf(fmt_buffer, size_buffer,
2492 "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x "
2493 "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x \n",
2494 val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7],
2495 val[8], val[9], val[10], val[11], val[12], val[13], val[14], val[15]);
2496 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "%s", fmt_buffer);
2497 return ret;
2498}
2499
2500int32_t format_serno_v1(const struct a6_device_state* state, const uint8_t* val,
2501 uint8_t* fmt_buffer, uint32_t size_buffer)
2502{
2503 int32_t ret;
2504
2505 ret = scnprintf(fmt_buffer, size_buffer, "%02x%02x%02x%02x%02x%02x\n",
2506 val[0], val[1], val[2], val[3], val[4], val[5]);
2507 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "%s", fmt_buffer);
2508 return ret;
2509}
2510
2511int32_t format_serno_v2(const struct a6_device_state* state, const uint8_t* val,
2512 uint8_t* fmt_buffer, uint32_t size_buffer)
2513{
2514 int32_t ret;
2515
2516 ret = scnprintf(fmt_buffer, size_buffer, "%02x%02x%02x%02x%02x%02x%02x%02x\n",
2517 val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7]);
2518 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO, "%s", fmt_buffer);
2519 return ret;
2520}
2521
2522static ssize_t a6_get_reg_vals(struct device *dev, struct device_attribute *attr, uint8_t *vals, unsigned num_vals)
2523{
2524 struct i2c_client *client = to_i2c_client(dev);
2525 int32_t ret = 0;
2526 struct a6_register_desc* reg_desc;
2527 struct a6_device_state* state = i2c_get_clientdata(client);
2528
2529 // critsec for manipulating flags
2530 ret = mutex_lock_interruptible(&state->dev_mutex);
2531 if (ret) {
2532 printk(KERN_ERR "%s: mutex_lock_interruptible interrupted(1)\n", __func__);
2533 return -ERESTARTSYS;
2534 }
2535
2536 // are we busy?
2537 while (test_and_set_bit(DEVICE_BUSY_BIT, state->flags)) {
2538 // yes: are we in bootload phase?
2539 if (!test_bit(BOOTLOAD_ACTIVE_BIT, state->flags)) {
2540 // no: so go ahead and allow concurrent i2c ops (these are
2541 // synchronized separately to allow priority based execution).
2542 break;
2543 }
2544
2545 // in bootload phase: get on a waitq
2546 mutex_unlock(&state->dev_mutex);
2547 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: about to wait for device non-busy...\n", __func__);
2548
2549 // bootload bit set? wait to be cleared (at least 5 mins: in jiffies)
2550 ret = wait_event_interruptible_timeout(state->dev_busyq,
2551 !test_bit(BOOTLOAD_ACTIVE_BIT, state->flags), 300*HZ);
2552 if (!ret) {
2553 printk(KERN_ERR "%s: wait on device busy timed-out/interrupted\n", __func__);
2554 // reset busy state
2555 clear_bit(DEVICE_BUSY_BIT, state->flags);
2556 // and continue...
2557 }
2558
2559 // we're about to manipulate flags again: acquire critsec
2560 ret = mutex_lock_interruptible(&state->dev_mutex);
2561 if (ret) {
2562 printk(KERN_ERR "%s: mutex_lock_interruptible interrupted(2)\n", __func__);
2563 return -ERESTARTSYS;
2564 }
2565 }
2566
2567 // increment busy refcount
2568 state->busy_count++;
2569 // done with flags: exit critsec
2570 mutex_unlock(&state->dev_mutex);
2571
2572 reg_desc = container_of(attr, struct a6_register_desc, dev_attr);
2573
2574 memset(vals, 0, sizeof(vals[0])*num_vals);
2575 ret = a6_i2c_read_reg(client, reg_desc->id, reg_desc->num_ids, vals);
2576
2577 // reset busy state
2578 mutex_lock(&state->dev_mutex);
2579 // decrement busy refcount
2580 if (state->busy_count) {
2581 state->busy_count--;
2582 }
2583 if (!state->busy_count) {
2584 clear_bit(DEVICE_BUSY_BIT, state->flags);
2585 }
2586 mutex_unlock(&state->dev_mutex);
2587 wake_up_interruptible(&state->dev_busyq);
2588
2589 return ret;
2590}
2591
2592static ssize_t a6_generic_show(struct device *dev, struct device_attribute *attr, char *buf)
2593{
2594 int32_t ret = 0, i = 0;
2595 uint8_t vals[id_size];
2596 struct a6_register_desc* reg_desc;
2597 struct i2c_client *client = to_i2c_client(dev);
2598 struct a6_device_state* state = i2c_get_clientdata(client);
2599
2600 ret = a6_get_reg_vals(dev, attr, vals, id_size);
2601
2602 if (ret < 0) return ret;
2603
2604 reg_desc = container_of(attr, struct a6_register_desc, dev_attr);
2605
2606 if (reg_desc->format) {
2607 ret = reg_desc->format(state, vals, buf, PAGE_SIZE);
2608 }
2609 else {
2610 /* if output restricted to 2 8-bit values, show as int16_t
2611 (common case of msb+lsb retrieval) */
2612 if (2 == reg_desc->num_ids) {
2613 ret = scnprintf(buf, PAGE_SIZE, "%d\n", *(int16_t*)vals);
2614 }
2615 /* if output > or < 2 8-bit values, show as
2616 * space-delimited list of int8_t values
2617 */
2618 else {
2619 i = ret = 0;
2620 while(i < reg_desc->num_ids) {
2621 ret += scnprintf(buf+ret, PAGE_SIZE-ret, "%d ", (int8_t)vals[i]);
2622 i++;
2623 }
2624 ret += scnprintf(buf+ret, PAGE_SIZE-ret, "\n");
2625 }
2626
2627 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "Buffer: %s\n", buf);
2628 }
2629
2630#ifdef A6_DEBUG
2631 {
2632 uint8_t d_ids[reg_desc->num_ids * (4+2+1) + 1];
2633 uint8_t d_vals[reg_desc->num_ids * (2+2+1) + 1];
2634 int32_t i = 0, ret_ids = 0, ret_vals = 0;
2635
2636 while (i < reg_desc->num_ids) {
2637 ret_ids += sprintf(d_ids+ret_ids, "0x%04x ", reg_desc->id[i]);
2638 ret_vals += sprintf(d_vals+ret_vals, "0x%02x ", vals[i]);
2639 i++;
2640 }
2641
2642 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_INFO,
2643 "showing reg name: %s, num_ids: %d, ids: %s, vals: %s\n",
2644 reg_desc->debug_name, reg_desc->num_ids, d_ids, d_vals);
2645 }
2646#endif
2647
2648 return ret;
2649}
2650
2651static ssize_t a6_reg_get(struct device *dev, unsigned regnum, void *buf)
2652{
2653 int32_t ret = 0;
2654 uint8_t vals[id_size];
2655 struct i2c_client *client = to_i2c_client(dev);
2656 struct a6_device_state* state = i2c_get_clientdata(client);
2657 struct device_attribute *attr = &a6_register_desc_arr[regnum].dev_attr;
2658 int32_t rsense = (int32_t)state->cached_rsense_val;
2659
2660 ret = a6_get_reg_vals(dev, attr, vals, id_size);
2661
2662 if (ret < 0) {
2663 printk(KERN_ERR "%s: a6_get_reg_vals failed for regnum %u\n",
2664 __func__, regnum);
2665 return ret;
2666 }
2667
2668 ret = 0;
2669
2670 switch (regnum) {
2671 case A6_REG_TS2_I2C_FLAGS_2:
2672 {
2673 uint32_t *out_val = (uint32_t*)buf;
2674 *out_val = *vals;
2675 }
2676 break;
2677 case A6_REG_TS2_I2C_BAT_RARC:
2678 {
2679 int32_t *out_val = (int32_t*)buf;
2680 *out_val = *vals;
2681 }
2682 break;
2683 case A6_REG_TS2_I2C_BAT_AVG_CUR_LSB_MSB:
2684 case A6_REG_TS2_I2C_BAT_CUR_LSB_MSB:
2685 {
2686 int32_t *out_val = (int32_t*)buf;
2687 *out_val = *(int16_t*)vals;
2688 *out_val = (*out_val * 3125) / 2 / rsense;
2689 }
2690 break;
2691 case A6_REG_TS2_I2C_BAT_VOLT_LSB_MSB:
2692 {
2693 int32_t *out_val = (int32_t*)buf;
2694 *out_val = *(int16_t*)vals;
2695 *out_val = (*out_val >> 5) * 4800;
2696 }
2697 break;
2698 case A6_REG_TS2_I2C_BAT_FULL40_LSB_MSB:
2699 case A6_REG_TS2_I2C_BAT_COULOMB_LSB_MSB:
2700 {
2701 int32_t *out_val = (int32_t*)buf;
2702 *out_val = *(int16_t*)vals;
2703 *out_val = (*out_val * 6250) / rsense;
2704 }
2705 break;
2706 case A6_REG_TS2_I2C_BAT_TEMP_LSB_MSB:
2707 {
2708 int32_t *out_val = (int32_t*)buf;
2709 int8_t temp_val = ((int8_t*)vals)[1];
2710 *out_val = temp_val * 10;
2711 }
2712 break;
2713 default:
2714 {
2715 printk(KERN_ERR "%s: Invalid register %u\n", __func__, regnum);
2716 ret = -EINVAL;
2717 }
2718 }
2719
2720 return ret;
2721}
2722
2723// constraints:
2724// * multi-valued stores must have individual values delimited by whitespace
2725// * multi-valued stores have individual values constrained to reg size (8-bit)
2726// * single-valued stores can specify 16-bit values to update two regs (msb+lsb)
2727// * value count must exactly match for multi-values stores
2728// * value-count for single value stores may be one less than the reg count specified.
2729static ssize_t a6_generic_store(struct device *dev, struct device_attribute *attr, const char *buf,
2730 size_t count)
2731{
2732 struct i2c_client *client = to_i2c_client(dev);
2733 int32_t ret = 0, num_ids, val_cnt, i;
2734 uint32_t val;
2735 char *endp = NULL, *bufp;
2736 uint16_t parsed_vals[id_size];
2737 uint8_t in_vals[id_size];
2738 struct a6_register_desc* reg_desc;
2739 struct a6_device_state* state = i2c_get_clientdata(client);
2740
2741 // critsec for manipulating flags
2742 ret = mutex_lock_interruptible(&state->dev_mutex);
2743 if (ret) {
2744 printk(KERN_ERR "%s: mutex_lock_interruptible interrupted(1)\n", __func__);
2745 return -ERESTARTSYS;
2746 }
2747
2748 // are we busy?
2749 while (test_and_set_bit(DEVICE_BUSY_BIT, state->flags)) {
2750 // yes: are we in bootload phase?
2751 if (!test_bit(BOOTLOAD_ACTIVE_BIT, state->flags)) {
2752 // no: so go ahead and allow concurrent i2c ops (these are
2753 // synchronized separately to allow priority based execution).
2754 break;
2755 }
2756
2757 // in bootload phase: get on a waitq
2758 mutex_unlock(&state->dev_mutex);
2759 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: about to wait for device non-busy...\n", __func__);
2760
2761 // bootload bit set? wait to be cleared (at least 5 mins: in jiffies)
2762 ret = wait_event_interruptible_timeout(state->dev_busyq,
2763 !test_bit(BOOTLOAD_ACTIVE_BIT, state->flags), 300*HZ);
2764 if (!ret) {
2765 printk(KERN_ERR "%s: wait on device busy timed-out/interrupted\n", __func__);
2766 // reset busy state
2767 clear_bit(DEVICE_BUSY_BIT, state->flags);
2768 // and continue...
2769 }
2770
2771 // we're about to manipulate flags again: acquire critsec
2772 ret = mutex_lock_interruptible(&state->dev_mutex);
2773 if (ret) {
2774 printk(KERN_ERR "%s: mutex_lock_interruptible interrupted(2)\n", __func__);
2775 return -ERESTARTSYS;
2776 }
2777 }
2778
2779 // increment busy refcount
2780 state->busy_count++;
2781 // done with flags: exit critsec
2782 mutex_unlock(&state->dev_mutex);
2783
2784 reg_desc = container_of(attr, struct a6_register_desc, dev_attr);
2785 num_ids = reg_desc->num_ids;
2786
2787 if (reg_desc->r_format)
2788 {
2789 ret = reg_desc->r_format(state, buf, in_vals, count);
2790 }
2791 else
2792 {
2793 bufp = (char*)buf;
2794 val_cnt = 0;
2795 do {
2796 // let strtoul perform base determination (handles '0x' and '0' prefixes) ...
2797 val = (uint16_t)simple_strtoul(bufp, &endp, 0);
2798 // each space-delimited write unit is capped at 16 bits...
2799 if (val > 0xffff) {
2800 ret = -EINVAL;
2801 goto err0;
2802 }
2803
2804 parsed_vals[val_cnt] = val;
2805
2806 // skip whitespace
2807 while (*endp && isspace(*endp)) {
2808 endp++;
2809 }
2810 // reset for next iteration
2811 bufp = endp;
2812 } while ((++val_cnt < num_ids) && ((endp - buf) < count));
2813
2814 // three levels of value count calidation:
2815 // * if extra values: fail
2816 // * if multiple values and does not match reg count specified: fail
2817 // * if single value and reg count > 2: fail
2818 if (*endp) {
2819 ret = -EINVAL;
2820 goto err0;
2821 }
2822 else if (val_cnt > 1) {
2823 if (val_cnt != num_ids) {
2824 ret = -EINVAL;
2825 goto err0;
2826 }
2827 }
2828 else {
2829 if (num_ids > 2) {
2830 ret = -EINVAL;
2831 goto err0;
2832 }
2833 }
2834
2835 // if multi-valued store or single-valued store to one reg: we constrain each
2836 // value to reg size (8 bits)
2837 if ((val_cnt > 1) || (1 == num_ids)) {
2838 for (i = 0; i < val_cnt; i++) {
2839 if (parsed_vals[i] > 0xff) {
2840 ret = -EINVAL;
2841 goto err0;
2842 }
2843
2844 in_vals[i] = parsed_vals[i];
2845 }
2846 }
2847 // single-valued store can be 8-bit or 16-bit (for msb+lsb)
2848 else {
2849 ((uint16_t*)in_vals)[0] = ((uint16_t*)parsed_vals)[0];
2850 }
2851 }
2852
2853#ifdef A6_DEBUG
2854 {
2855 uint8_t d_ids[reg_desc->num_ids * (4+2+1)];
2856 uint8_t d_vals[reg_desc->num_ids * (2+2+1)];
2857 int32_t i = 0, ret_ids = 0, ret_vals = 0;
2858
2859 while (i < reg_desc->num_ids) {
2860 ret_ids = sprintf(d_ids+ret_ids, "0x%04x ", reg_desc->id[i]);
2861 ret_vals = sprintf(d_vals+ret_vals, "0x%02x ", in_vals[i]);
2862 i++;
2863 }
2864
2865 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR,
2866 "storing reg name: %s, num_ids: %d, ids: %s, vals: %s\n",
2867 reg_desc->debug_name, reg_desc->num_ids, d_ids, d_vals);
2868 }
2869#endif
2870
2871 ret = a6_i2c_write_reg(client, reg_desc->id, num_ids, in_vals);
2872 if (ret < 0) {
2873 goto err0;
2874 }
2875
2876 ret = count;
2877
2878err0:
2879 // reset busy state
2880 mutex_lock(&state->dev_mutex);
2881 // decrement busy refcount
2882 if (state->busy_count) {
2883 state->busy_count--;
2884 }
2885 if (!state->busy_count) {
2886 clear_bit(DEVICE_BUSY_BIT, state->flags);
2887 }
2888 mutex_unlock(&state->dev_mutex);
2889 wake_up_interruptible(&state->dev_busyq);
2890
2891 return ret;
2892}
2893
2894enum {
2895 ACTIVATE_EXTRACT,
2896 NONE
2897};
2898
2899static ssize_t a6_val_cksum_show(struct device *dev, struct device_attribute *attr, char *buf)
2900{
2901 struct i2c_client *client = to_i2c_client(dev);
2902 int32_t rc = 0, reloop = 0, failed = 0;
2903 struct a6_device_state* state = i2c_get_clientdata(client);
2904 uint16_t cksum1, cksum2, cksum_cycles, cksum_errors;
2905 struct a6_register_desc *reg_desc;
2906 uint8_t vals[id_size];
2907
2908
2909 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: enter\n", __func__);
2910
2911 // critsec for manipulating flags
2912 rc = mutex_lock_interruptible(&state->dev_mutex);
2913 if (rc) {
2914 printk(KERN_ERR "%s: mutex_lock interrupted\n", __func__);
2915 return -EIO;
2916 }
2917
2918 // are we busy?
2919 while (test_and_set_bit(DEVICE_BUSY_BIT, state->flags)) {
2920 // yes: get on a waitq
2921 mutex_unlock(&state->dev_mutex);
2922
2923 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: about to wait for device non-busy...\n", __func__);
2924
2925 // busy bit set? wait to be cleared (at least 5 minutes: in jiffies)
2926 rc = wait_event_interruptible_timeout(state->dev_busyq,
2927 !test_bit(DEVICE_BUSY_BIT, state->flags), 300*HZ);
2928 if (!rc) {
2929 printk(KERN_ERR "%s: wait on device busy timed-out/interrupted\n", __func__);
2930 // reset busy state
2931 clear_bit(DEVICE_BUSY_BIT, state->flags);
2932 // and continue...
2933 }
2934
2935 // we're about to manipulate flags again: acquire critsec
2936 rc = mutex_lock_interruptible(&state->dev_mutex);
2937 if (rc) {
2938 printk(KERN_ERR "%s: mutex_lock interrupted(2)\n", __func__);
2939 goto err0;
2940 }
2941 }
2942
2943 rc = test_and_set_bit(BOOTLOAD_ACTIVE_BIT, state->flags);
2944 ASSERT(!rc);
2945
2946 // we're done with flags: exit critsec
2947 mutex_unlock(&state->dev_mutex);
2948
2949 do {
2950 /* write command (cksum1) */
2951 reg_desc = &a6_register_desc_arr[35];
2952 vals[0] = TS2_I2C_COMMAND_FRAM_CHECKSUM_READ_1;
2953 rc = a6_i2c_write_reg(state->i2c_dev, reg_desc->id, reg_desc->num_ids, vals);
2954 if (rc < 0) {
2955 printk(KERN_ERR "%s: error writing reg: %s, id: 0x%x\n",
2956 __func__, reg_desc->debug_name, reg_desc->id[0]);
2957 break;
2958 }
2959
2960 /* read cksum1 */
2961 reg_desc = &a6_register_desc_arr[80];
2962 memset(vals, 0, sizeof(vals));
2963 rc = a6_i2c_read_reg(state->i2c_dev, reg_desc->id, reg_desc->num_ids, vals);
2964 if (rc < 0) {
2965 printk(KERN_ERR "%s: error reading reg: %s, ids: 0x%x 0x%x\n",
2966 __func__, reg_desc->debug_name, reg_desc->id[0], reg_desc->id[1]);
2967 break;
2968 }
2969 cksum1 = vals[0] | vals[1] << 8;
2970
2971 /* read cksum cycle counter */
2972 reg_desc = &a6_register_desc_arr[81];
2973 memset(vals, 0, sizeof(vals));
2974 rc = a6_i2c_read_reg(state->i2c_dev, reg_desc->id, reg_desc->num_ids, vals);
2975 if (rc < 0) {
2976 printk(KERN_ERR "%s: error reading reg: %s, ids: 0x%x 0x%x\n",
2977 __func__, reg_desc->debug_name, reg_desc->id[0], reg_desc->id[1]);
2978 break;
2979 }
2980 cksum_cycles = vals[0] | vals[1] << 8;
2981
2982 /* write command (cksum2) */
2983 reg_desc = &a6_register_desc_arr[35];
2984 vals[0] = TS2_I2C_COMMAND_FRAM_CHECKSUM_READ_2;
2985 rc = a6_i2c_write_reg(state->i2c_dev, reg_desc->id, reg_desc->num_ids, vals);
2986 if (rc < 0) {
2987 printk(KERN_ERR "%s: error writing reg: %s, id: 0x%x\n",
2988 __func__, reg_desc->debug_name, reg_desc->id[0]);
2989 break;
2990 }
2991
2992 /* read cksum2 */
2993 reg_desc = &a6_register_desc_arr[80];
2994 memset(vals, 0, sizeof(vals));
2995 rc = a6_i2c_read_reg(state->i2c_dev, reg_desc->id, reg_desc->num_ids, vals);
2996 if (rc < 0) {
2997 printk(KERN_ERR "%s: error reading reg: %s, ids: 0x%x 0x%x\n",
2998 __func__, reg_desc->debug_name, reg_desc->id[0], reg_desc->id[1]);
2999 break;
3000 }
3001 cksum2 = vals[0] | vals[1] << 8;
3002
3003 /* read cksum error counter */
3004 reg_desc = &a6_register_desc_arr[81];
3005 memset(vals, 0, sizeof(vals));
3006 rc = a6_i2c_read_reg(state->i2c_dev, reg_desc->id, reg_desc->num_ids, vals);
3007 if (rc < 0) {
3008 printk(KERN_ERR "%s: error reading reg: %s, ids: 0x%x 0x%x\n",
3009 __func__, reg_desc->debug_name, reg_desc->id[0], reg_desc->id[1]);
3010 break;
3011 }
3012 cksum_errors = vals[0] | vals[1] << 8;
3013
3014 /* validate cksum */
3015 if (reloop || !cksum1 || !cksum2 || (cksum1 != cksum2)) {
3016 printk(KERN_ERR "A6 checksum (%s) validation failure:\n"
3017 "cksum1: 0x%02hx; cksum2: 0x%02hx; cksum_cycles: 0x%02hx;"
3018 " cksum_errors: 0x%02hx\n",
3019 (!reloop) ? "first-stage" : "second-stage",
3020 cksum1, cksum2, cksum_cycles, cksum_errors);
3021 if (reloop) {
3022 reloop--;
3023 failed = 1;
3024 }
3025 else {
3026 reloop++;
3027 }
3028 }
3029 } while (reloop);
3030
3031 if (rc < 0) {
3032 printk(KERN_ERR "%s: checksum retrieval enountered i2c errors: "
3033 "fallback to sbw(jtag) access.\n", __func__);
3034 get_checksum_data_sbw((struct a6_sbw_interface*)state->plat_data->sbw_ops, &cksum1,
3035 &cksum2, &cksum_cycles, &cksum_errors);
3036 }
3037
3038 /* validate cksum */
3039 if (failed || !cksum1 || !cksum2 || (cksum1 != cksum2)) {
3040 printk(KERN_ERR "A6 checksum validation failed:\n"
3041 "cksum1: 0x%02hx; cksum2: 0x%02hx; cksum_cycles: 0x%02hx;"
3042 " cksum_errors: 0x%02hx\n",
3043 cksum1, cksum2, cksum_cycles, cksum_errors);
3044 rc = snprintf(buf, PAGE_SIZE, "%d\n", 0);
3045 }
3046 else {
3047 rc = snprintf(buf, PAGE_SIZE, "%d\n", 1);
3048 }
3049
3050err0:
3051 mutex_lock(&state->dev_mutex);
3052 clear_bit(BOOTLOAD_ACTIVE_BIT, state->flags);
3053 clear_bit(DEVICE_BUSY_BIT, state->flags);
3054 mutex_unlock(&state->dev_mutex);
3055 wake_up_interruptible(&state->dev_busyq);
3056
3057 return rc;
3058}
3059
3060
3061static char* activation_strlist[] = {
3062 [ACTIVATE_EXTRACT] = "extract",
3063 [NONE] = "none"
3064};
3065
3066static ssize_t a6_diag_store(struct device *dev, struct device_attribute *attr, const char *buf,
3067 size_t count)
3068{
3069 struct i2c_client *client = to_i2c_client(dev);
3070 int32_t rc = 0, ret_val, action_i = 0;
3071 struct a6_device_state* state = i2c_get_clientdata(client);
3072 bool skip = false;
3073
3074 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: enter\n", __func__);
3075
3076 action_i = (sizeof(activation_strlist)/sizeof(char*));
3077 do {
3078 if (0 == strncmp(buf, activation_strlist[action_i-1],
3079 strlen(activation_strlist[action_i-1]))) {
3080 break;
3081 }
3082 } while(action_i--);
3083
3084 if (!action_i) {
3085 return -EINVAL;
3086 }
3087
3088 // store the action index
3089 action_i--;
3090
3091 // critsec for manipulating flags
3092 rc = mutex_lock_interruptible(&state->dev_mutex);
3093 if (rc) {
3094 printk(KERN_ERR "%s: mutex_lock interrupted\n", __func__);
3095 return -EIO;
3096 }
3097
3098 // are we busy?
3099 while (test_and_set_bit(DEVICE_BUSY_BIT, state->flags)) {
3100 // yes: get on a waitq
3101 mutex_unlock(&state->dev_mutex);
3102
3103 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: about to wait for device non-busy...\n", __func__);
3104
3105 // busy bit set? wait to be cleared (at least 5 minutes: in jiffies)
3106 rc = wait_event_interruptible_timeout(state->dev_busyq,
3107 !test_bit(DEVICE_BUSY_BIT, state->flags), 300*HZ);
3108 if (!rc) {
3109 printk(KERN_ERR "%s: wait on device busy timed-out/interrupted\n", __func__);
3110 // reset busy state
3111 clear_bit(DEVICE_BUSY_BIT, state->flags);
3112 // and continue...
3113 }
3114
3115 // we're about to manipulate flags again: acquire critsec
3116 rc = mutex_lock_interruptible(&state->dev_mutex);
3117 if (rc) {
3118 printk(KERN_ERR "%s: mutex_lock interrupted(2)\n", __func__);
3119 goto err0;
3120 }
3121 }
3122
3123 if (ACTIVATE_EXTRACT == action_i) {
3124 if (test_bit(EXTRACT_INITIATED, state->flags)) {
3125 skip = true;
3126 }
3127 else {
3128 ret_val = test_and_set_bit(BOOTLOAD_ACTIVE_BIT, state->flags);
3129 ASSERT(!ret_val);
3130 ret_val = test_and_set_bit(EXTRACT_INITIATED, state->flags);
3131 ASSERT(!ret_val);
3132 }
3133 }
3134 else if (NONE == action_i) {
3135 if (!(test_bit(EXTRACT_INITIATED, state->flags))) {
3136 skip = true;
3137 }
3138 }
3139 else {
3140 // invalid
3141 }
3142
3143 // we're done with flags: exit critsec
3144 mutex_unlock(&state->dev_mutex);
3145
3146 if (true == skip) goto err0;
3147
3148 if (ACTIVATE_EXTRACT == action_i) {
3149 // reset force-wake state to always force wake on first i2c txn
3150 // after pmem extraction
3151 del_timer(&state->a6_force_wake_timer);
3152 mutex_lock(&state->a6_force_wake_mutex);
3153 if (test_bit(CAP_PERIODIC_WAKE, state->flags)) {
3154 clear_bit(FORCE_WAKE_ACTIVE_BIT, state->flags);
3155 }
3156 mutex_unlock(&state->a6_force_wake_mutex);
3157
3158 // start pmem extract
3159 printk(KERN_ERR "%s: starting ttf_extract.\n", __func__);
3160 rc = ttf_extract_fw_sbw((struct a6_sbw_interface*)state->plat_data->sbw_ops);
3161 if (rc) {
3162 printk(KERN_ERR "Failed to ttf_extract a6 pmem.\n");
3163 goto err0;
3164 }
3165 else {
3166 printk(KERN_ERR "A6: Completed ttf_extract a6 pmem.\n");
3167 // wait for the A6 to boot...
3168 msleep(3000);
3169 // - re-init state
3170 // - if init fails: ignore
3171 a6_init_state(state->i2c_dev);
3172 }
3173 }
3174 else if (NONE == action_i) {
3175 printk(KERN_ERR "%s: clearing ttf_extract cache.\n", __func__);
3176 rc = ttf_extract_cache_clear();
3177 }
3178 else {
3179 // invalid
3180 }
3181
3182err0:
3183 mutex_lock(&state->dev_mutex);
3184 if (false == skip) {
3185 if (rc || NONE == action_i) {
3186 if (test_bit(EXTRACT_INITIATED, state->flags)) {
3187 clear_bit(EXTRACT_INITIATED, state->flags);
3188 }
3189 }
3190 if (test_bit(BOOTLOAD_ACTIVE_BIT, state->flags)) {
3191 clear_bit(BOOTLOAD_ACTIVE_BIT, state->flags);
3192 }
3193 }
3194 clear_bit(DEVICE_BUSY_BIT, state->flags);
3195 mutex_unlock(&state->dev_mutex);
3196 wake_up_interruptible(&state->dev_busyq);
3197
3198 return (rc ? rc : count);
3199}
3200
3201static ssize_t a6_diag_show(struct device *dev, struct device_attribute *attr, char *buf)
3202{
3203 struct i2c_client *client = to_i2c_client(dev);
3204 int32_t rc = 0;
3205 struct a6_device_state* state = i2c_get_clientdata(client);
3206
3207
3208 mutex_lock(&state->dev_mutex);
3209 if (test_bit(EXTRACT_INITIATED, state->flags)) {
3210 rc = snprintf(buf, PAGE_SIZE, "%s\n", activation_strlist[ACTIVATE_EXTRACT]);
3211 }
3212 mutex_unlock(&state->dev_mutex);
3213
3214 return rc;
3215}
3216
3217int32_t a6_create_dev_files(struct a6_device_state* state, struct device* dev)
3218{
3219 int32_t rc = 0, reg_cnt = sizeof(a6_register_desc_arr)/sizeof(struct a6_register_desc);
3220 int32_t idx = 0, cust_idx = 0;
3221
3222 for (idx = 0; idx < reg_cnt; idx++) {
3223 rc = device_create_file(dev, &a6_register_desc_arr[idx].dev_attr);
3224 if (rc < 0) {
3225 printk(KERN_ERR "%s: failed to create dev_attr file for %s.\n",
3226 __func__, a6_register_desc_arr[idx].dev_attr.attr.name);
3227 goto err0;
3228 }
3229 }
3230
3231 reg_cnt = sizeof(custom_devattr)/sizeof(struct device_attribute);
3232 for (cust_idx = 0; cust_idx < reg_cnt; cust_idx++) {
3233 rc = device_create_file(dev, &custom_devattr[cust_idx]);
3234 if (rc < 0) {
3235 printk(KERN_ERR "%s: failed to create dev_attr file for %s.\n",
3236 __func__, custom_devattr[cust_idx].attr.name);
3237 goto err0;
3238 }
3239 }
3240
3241 rc = sysfs_create_link(&state->mdev.this_device->kobj, &dev->kobj, "regs");
3242 if (rc) {
3243 printk(KERN_ERR "%s: error in creating symlink.\n", __func__);
3244 }
3245
3246 return 0;
3247
3248err0:
3249 // error: cleanup files already created.
3250 for (idx--; idx >= 0; idx--) {
3251 device_remove_file(dev, &a6_register_desc_arr[idx].dev_attr);
3252 }
3253 for (cust_idx--; cust_idx >= 0; cust_idx--) {
3254 device_remove_file(dev, &custom_devattr[cust_idx]);
3255 }
3256 return rc;
3257
3258}
3259
3260void a6_remove_dev_files(struct a6_device_state* state, struct device* dev)
3261{
3262 int32_t reg_cnt = sizeof(a6_register_desc_arr)/sizeof(struct a6_register_desc);
3263 int32_t idx;
3264
3265 for (idx = 0; idx < reg_cnt; idx++) {
3266 device_remove_file(dev, &a6_register_desc_arr[idx].dev_attr);
3267 }
3268
3269 reg_cnt = sizeof(custom_devattr)/sizeof(struct device_attribute);
3270 for (idx = 0; idx < reg_cnt; idx++) {
3271 device_remove_file(dev, &custom_devattr[idx]);
3272 }
3273}
3274
3275typedef enum {
3276 A6_PROGAM_AND_VERIFY_FW = 1,
3277 A6_VERIFY_FW
3278} a6_pgm_thread_op;
3279
3280struct a6_pgm_thread_params {
3281 struct a6_sbw_interface* sbw_ops;
3282 uint32_t buffer_p;
3283 int32_t ret_code;
3284 a6_pgm_thread_op op;
3285 struct completion a6_flash_thread_nice;
3286 struct completion a6_flash_thread_exit;
3287};
3288
3289int a6_pgm_thread_fn(void* param)
3290{
3291 int32_t ret_val;
3292
3293 struct a6_pgm_thread_params* t_p = (struct a6_pgm_thread_params*)param;
3294
3295 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: buffer_p val: 0x%x\n", __func__, t_p->buffer_p);
3296
3297 // wait for parent re-nice completion...
3298 ret_val = wait_for_completion_interruptible(&t_p->a6_flash_thread_nice);
3299 if (-ERESTARTSYS == ret_val) {
3300 printk(KERN_ERR "A6: waiting for parent re-nice completion interrupted.\n");
3301 t_p->ret_code = -EINTR;
3302 goto err0;
3303 }
3304
3305 if (A6_PROGAM_AND_VERIFY_FW == t_p->op) {
3306 ret_val = program_device_sbw(t_p->sbw_ops, t_p->buffer_p);
3307 }
3308 else {
3309 ret_val = verify_device_sbw(t_p->sbw_ops, t_p->buffer_p);
3310 // ignore error returns for the moment as the verification fn
3311 // does not differentiate between code and r/w data sections.
3312 // also, the fw section allocation changes fairly dynamically
3313 // between fw drops and we don't yet support parameterizing the
3314 // section map for the verification code.
3315 ret_val = 0;
3316 }
3317 if (ret_val) {
3318 t_p->ret_code = -EINVAL;
3319 }
3320
3321 // signal thread completion
3322 complete(&t_p->a6_flash_thread_exit);
3323
3324err0:
3325 return 0;
3326}
3327
3328static long a6_ioctl(struct file *file,
3329 unsigned int cmd, unsigned long args)
3330{
3331 int32_t rc = 0;
3332 struct a6_device_state* state = file->private_data;
3333 void* usr_ptr = (void*)args;
3334 //uint32_t usr_bytes = _IOC_SIZE(cmd);
3335 //uint32_t usr_val = 0x0;
3336
3337 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: cmd: %d\n", __func__, _IOC_NR(cmd));
3338
3339 // critsec for manipulating flags
3340 rc = mutex_lock_interruptible(&state->dev_mutex);
3341 if (rc) {
3342 printk(KERN_ERR "%s: mutex_lock interrupted(1)\n", __func__);
3343 return -ERESTARTSYS;
3344 }
3345
3346 // are we busy?
3347 while (test_and_set_bit(DEVICE_BUSY_BIT, state->flags)) {
3348 // yes: get on a waitq
3349 mutex_unlock(&state->dev_mutex);
3350
3351 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: about to wait for device non-busy...\n", __func__);
3352
3353 // busy bit set? wait to be cleared (at least 3 seconds: in jiffies)
3354 rc = wait_event_interruptible_timeout(state->dev_busyq,
3355 !test_bit(DEVICE_BUSY_BIT, state->flags), 3*HZ);
3356 if (!rc) {
3357 printk(KERN_ERR "%s: wait on device busy timed-out/interrupted\n", __func__);
3358 // reset busy state
3359 clear_bit(DEVICE_BUSY_BIT, state->flags);
3360 // and continue...
3361 }
3362
3363 // we're about to manipulate flags again: acquire critsec
3364 rc = mutex_lock_interruptible(&state->dev_mutex);
3365 if (rc) {
3366 printk(KERN_ERR "%s: mutex_lock interrupted(2)\n", __func__);
3367 return -ERESTARTSYS;
3368 }
3369 }
3370
3371 // bootload request: set flag in critsec
3372 if (A6_IOCTL_SET_FW_DATA == cmd || A6_IOCTL_VERIFY_FW_DATA == cmd) {
3373 int32_t ret_val;
3374 ret_val = test_and_set_bit(BOOTLOAD_ACTIVE_BIT, state->flags);
3375 ASSERT(!ret_val);
3376 }
3377
3378 // we're done with flags: exit critsec
3379 mutex_unlock(&state->dev_mutex);
3380
3381 switch (cmd) {
3382 case A6_IOCTL_SET_FW_DATA:
3383 case A6_IOCTL_VERIFY_FW_DATA:
3384 {
3385 uint8_t *buffer_p = NULL;
3386 uint32_t payload_size = 0;
3387 struct a6_sbw_interface* sbw_ops =
3388 (struct a6_sbw_interface*)state->plat_data->sbw_ops;
3389 uint8_t* a6_fw_buffer;
3390 struct task_struct* pgm_worker_task;
3391 pid_t pgm_worker_task_pid;
3392 struct a6_pgm_thread_params t_params;
3393
3394 // reset force-wake state to always force wake on first i2c txn
3395 // after flashing/verification
3396 del_timer(&state->a6_force_wake_timer);
3397 mutex_lock(&state->a6_force_wake_mutex);
3398 if (test_bit(CAP_PERIODIC_WAKE, state->flags)) {
3399 clear_bit(FORCE_WAKE_ACTIVE_BIT, state->flags);
3400 }
3401 mutex_unlock(&state->a6_force_wake_mutex);
3402
3403 // copy payload ptr from ioctl parameter
3404 if (copy_from_user(&buffer_p, usr_ptr, sizeof(buffer_p))) {
3405 rc = -EFAULT;
3406 break;
3407 }
3408 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "buffer_p val: 0x%p\n", buffer_p);
3409
3410 // copy payload size from ioctl parameter
3411 if (copy_from_user(&payload_size, (uint8_t*)usr_ptr + sizeof(uint32_t), sizeof(payload_size))) {
3412 rc = -EFAULT;
3413 break;
3414 }
3415
3416 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "payload_size: %d\n", payload_size);
3417
3418 // alloc kernel buffer for payload
3419 a6_fw_buffer = (uint8_t*)kmalloc(payload_size, GFP_KERNEL);
3420 if (!a6_fw_buffer) {
3421 printk(KERN_ERR "A6: failed to allocate fw buffer.\n");
3422 rc = -ENOMEM;
3423 break;
3424 }
3425 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "fw buffer ptr_val: 0x%p\n", a6_fw_buffer);
3426
3427 // copy-in payload data
3428 if (copy_from_user(a6_fw_buffer, buffer_p, payload_size)) {
3429 rc = -EFAULT;
3430 break;
3431 }
3432
3433 printk(KERN_ERR "A6: Starting flashing sequence.\n");
3434 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "A6: parent task nice value: %d; pri: %d\n",
3435 task_nice(current), task_prio(current));
3436
3437 // initialize worker task params
3438 init_completion(&t_params.a6_flash_thread_nice);
3439 init_completion(&t_params.a6_flash_thread_exit);
3440 t_params.sbw_ops = sbw_ops;
3441 t_params.buffer_p = (uint32_t)a6_fw_buffer;
3442 t_params.ret_code = 0;
3443 t_params.op = (A6_IOCTL_SET_FW_DATA == cmd) ?
3444 A6_PROGAM_AND_VERIFY_FW : A6_VERIFY_FW;
3445
3446 // create worker task...
3447 pgm_worker_task_pid = kernel_thread(a6_pgm_thread_fn, &t_params,
3448 CLONE_KERNEL);
3449 if (pgm_worker_task_pid < 0) {
3450 printk(KERN_ERR "A6: failed to create pgm worker task.\n");
3451 rc = -EIO;
3452 break;
3453 }
3454
3455 // retrieve worker task struct
3456 pgm_worker_task = get_pid_task(find_get_pid(pgm_worker_task_pid), PIDTYPE_PID);
3457 // re-nice worker task
3458 //set_user_nice(pgm_worker_task, 10);
3459 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "A6: pgm worker task nice value: %d; pri: %d\n",
3460 task_nice(pgm_worker_task), task_prio(pgm_worker_task));
3461
3462 /* hold cpu at max freq before signaling worker thread to commence sbw */
3463#ifdef CONFIG_CPU_FREQ_GOV_ONDEMAND_TICKLE
3464 CPUFREQ_HOLD_CHECK(&state->cpufreq_hold_flag);
3465#endif
3466 // signal re-nice completion...
3467 complete(&t_params.a6_flash_thread_nice);
3468
3469 // wait for worker task-end completion...
3470 rc = wait_for_completion_interruptible(&t_params.a6_flash_thread_exit);
3471 /* unhold cpu */
3472#ifdef CONFIG_CPU_FREQ_GOV_ONDEMAND_TICKLE
3473 CPUFREQ_UNHOLD_CHECK(&state->cpufreq_hold_flag);
3474#endif
3475 kfree(a6_fw_buffer);
3476
3477 if (-ERESTARTSYS == rc) {
3478 printk(KERN_ERR "A6: waiting for pgm worker start interrupted.\n");
3479 break;
3480 }
3481
3482 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "A6: pgm worker task exit code: %d\n",
3483 t_params.ret_code);
3484 if (t_params.ret_code) {
3485 printk(KERN_ERR "A6: Failed to completed flashing sequence. ret: %d\n",
3486 t_params.ret_code);
3487 // propagate error to caller...
3488 rc = t_params.ret_code;
3489 }
3490 else {
3491 printk(KERN_ERR "A6: Completed flashing sequence.\n");
3492 // wait for the A6 to boot...
3493 msleep(3000);
3494 // - flashing fw forces a device power-up sequence: re-init state
3495 // - if init fails: treat as fw flash failure by returning rc
3496 rc = a6_init_state(state->i2c_dev);
3497 if (rc < 0) {
3498 printk(KERN_ERR "%s: failed to initialize, err: %d\n", A6_DRIVER, rc);
3499 }
3500 }
3501
3502 mutex_lock(&state->dev_mutex);
3503 clear_bit(BOOTLOAD_ACTIVE_BIT, state->flags);
3504 mutex_unlock(&state->dev_mutex);
3505 }
3506 break;
3507
3508 default:
3509 {
3510 rc = -EINVAL;
3511 }
3512 break;
3513 }
3514
3515
3516//Done:
3517 mutex_lock(&state->dev_mutex);
3518 if (rc) {
3519 if (test_bit(BOOTLOAD_ACTIVE_BIT, state->flags)) {
3520 clear_bit(BOOTLOAD_ACTIVE_BIT, state->flags);
3521 }
3522 clear_bit(DEVICE_BUSY_BIT, state->flags);
3523 }
3524 else {
3525 if (!test_bit(BOOTLOAD_ACTIVE_BIT, state->flags)) {
3526 clear_bit(DEVICE_BUSY_BIT, state->flags);
3527 }
3528 }
3529 mutex_unlock(&state->dev_mutex);
3530
3531 wake_up_interruptible(&state->dev_busyq);
3532
3533 return rc;
3534}
3535
3536static int a6_open(struct inode *inode, struct file *file)
3537{
3538 struct a6_device_state* state;
3539
3540 /* get device */
3541 state = container_of(file->f_op, struct a6_device_state, fops);
3542
3543 /* Allow only read. */
3544 //if ((file->f_mode & (FMODE_READ|FMODE_WRITE)) != FMODE_READ) {
3545 // return -EINVAL;
3546 //}
3547
3548 ///* check if it is in use */
3549 //if (test_and_set_bit(IS_OPENED, state->flags)) {
3550 // return -EBUSY;
3551 //}
3552
3553 /* attach private data */
3554 file->private_data = state;
3555
3556 return 0;
3557}
3558
3559static int a6_close(struct inode *inode, struct file *file)
3560{
3561 struct a6_device_state* state = (struct a6_device_state*) file->private_data;
3562
3563 state = state;
3564 ///* mark it as unused */
3565 //clear_bit(IS_OPENED, state->flags);
3566
3567 return 0;
3568}
3569
3570#define A2A_DGRAM_PREAMBLE (0x5AC35AC3)
3571struct a2a_dgram_hdr {
3572 uint32_t preamble;
3573 uint16_t len;
3574 uint16_t cksum;
3575};
3576
3577static ssize_t a6_read(struct file *file, char __user *buf, size_t count, loff_t *ppos )
3578{
3579# define A2A_RX_MISS_THRESHOLD (300)
3580
3581 ssize_t rc = 0;
3582 struct a6_device_state* state;
3583 struct a6_register_desc *reg_desc_comm_status, *reg_desc_comm_rxtx;
3584 uint8_t vals[id_size];
3585 int32_t miss_count, rd_count;
3586 //struct a2a_dgram_hdr hdr;
3587 uint32_t start_time;
3588 uint8_t elt_val = 0, prev_byte;
3589
3590 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: enter\n", __func__);
3591
3592 start_time = jiffies;
3593 /* input validations */
3594 if (!count) {
3595 return -EINVAL;
3596 }
3597 else if (count > A2A_RD_BUFF_SIZE) {
3598 return -EFBIG;
3599 }
3600
3601 /* get state */
3602 state = container_of(file->f_op, struct a6_device_state, fops);
3603
3604 // acquire critsec
3605 rc = mutex_lock_interruptible(&state->dev_mutex);
3606 if (rc) {
3607 printk(KERN_ERR "%s: mutex_lock interrupted.\n", __func__);
3608 return -ERESTARTSYS;
3609 }
3610
3611 /* not connected? exit */
3612 if (!test_bit(A2A_CONNECTED, state->flags)) {
3613 mutex_unlock(&state->dev_mutex);
3614 printk(KERN_ERR "%s: no a2a connection detected.\n", __func__);
3615 return -EINVAL;
3616 }
3617
3618 // busy?
3619 if (test_and_set_bit(READ_ACTIVE_BIT, state->flags)) {
3620 // yes: get on a waitq
3621 mutex_unlock(&state->dev_mutex);
3622 printk(KERN_ERR "%s: re-entrant call disallowed.\n", __func__);
3623 return -EINVAL;
3624 }
3625
3626 mutex_unlock(&state->dev_mutex);
3627
3628 /* init a2a read ptr */
3629 state->a2a_rp = state->a2a_rd_buf;
3630
3631 rd_count = 0;
3632 miss_count = 0;
3633 prev_byte = 0;
3634 do {
3635 /* read comm status */
3636 reg_desc_comm_status = &a6_register_desc_arr[63];
3637 memset(vals, 0, sizeof(vals));
3638 rc = a6_i2c_read_reg(state->i2c_dev, reg_desc_comm_status->id,
3639 reg_desc_comm_status->num_ids, vals);
3640 if (rc < 0) {
3641 printk(KERN_ERR "%s: error reading reg: %s, id: 0x%x\n",
3642 __func__, reg_desc_comm_status->debug_name, reg_desc_comm_status->id[0]);
3643 goto err0;
3644 }
3645
3646 if (!(vals[0] & TS2_I2C_COMM_STATUS_RX_FULL)) {
3647 if (++miss_count > A2A_RX_MISS_THRESHOLD) {
3648 if (test_bit(A2A_CONNECTED, state->flags)) {
3649 continue;
3650 }
3651 else {
3652 break;
3653 }
3654 }
3655 continue;
3656 }
3657
3658 /* read rx data */
3659 memset(vals, 0, sizeof(vals));
3660 reg_desc_comm_rxtx = &a6_register_desc_arr[64];
3661 rc = a6_i2c_read_reg(state->i2c_dev, reg_desc_comm_rxtx->id,
3662 reg_desc_comm_rxtx->num_ids, vals);
3663 if (rc < 0) {
3664 printk(KERN_ERR "%s: error writing reg: %s, id: 0x%x\n",
3665 __func__, reg_desc_comm_rxtx->debug_name, reg_desc_comm_rxtx->id[0]);
3666 rc = -EIO;
3667 goto err0;
3668 }
3669
3670 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: read byte: %d successfully.\n",
3671 __func__, rd_count);
3672
3673 if (a6_t2s_dup_correct) {
3674 if ((prev_byte & 0x80) ^ (vals[0] & 0x80)) {
3675 prev_byte = vals[0];
3676 if (vals[0] & 0x80) {
3677 elt_val = _convert_hex_char_to_decimal(vals[0] & 0x7f) << 4;
3678 continue;
3679 }
3680 else {
3681 elt_val |= (_convert_hex_char_to_decimal(vals[0]) & 0x0f);
3682 }
3683 }
3684 else {
3685 printk(KERN_ERR "%s: t2s duplicate detected; char: 0x%02x.\n",
3686 __func__, vals[0]);
3687 continue;
3688 }
3689 }
3690 else {
3691 elt_val = vals[0];
3692 }
3693
3694 *state->a2a_rp = elt_val;
3695 state->a2a_rp++;
3696 rd_count++;
3697 } while (rd_count < count);
3698
3699 if (!rd_count) {
3700 printk(KERN_ERR "%s: rx failed; A2A connection terminated.\n", __func__);
3701 rc = -EINVAL;
3702 }
3703 else {
3704 long diff_time;
3705
3706 if (copy_to_user(buf, state->a2a_rd_buf, rd_count)) {
3707 rc = -EFAULT;
3708 goto err0;
3709 }
3710 rc = rd_count;
3711 diff_time = (long)jiffies - (long)start_time;
3712 printk(KERN_ERR "%s: elapsed time: %ld ms; count: %u\n",
3713 __func__, diff_time * 1000/HZ, rd_count);
3714 }
3715
3716
3717err0:
3718 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: exit\n", __func__);
3719 clear_bit(READ_ACTIVE_BIT, state->flags);
3720 return rc;
3721}
3722
3723static ssize_t a6_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos )
3724{
3725# define A2A_TX_MISS_THRESHOLD (300)
3726
3727 ssize_t rc = 0;
3728 struct a6_device_state* state;
3729 struct a6_register_desc *reg_desc_comm_status, *reg_desc_comm_rxtx;
3730 uint8_t vals[id_size];
3731 int32_t miss_count, wr_count;
3732 //struct a2a_dgram_hdr hdr;
3733 uint32_t start_time;
3734 uint8_t elt_buf[2], *elt_bufp = NULL;
3735 int elt_bufsize;
3736
3737 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: enter\n", __func__);
3738
3739 start_time = jiffies;
3740 /* input validations */
3741 if (!count) {
3742 return -EINVAL;
3743 }
3744 else if (count > A2A_WR_BUFF_SIZE) {
3745 return -EFBIG;
3746 }
3747
3748 /* get state */
3749 state = container_of(file->f_op, struct a6_device_state, fops);
3750
3751 // acquire critsec
3752 rc = mutex_lock_interruptible(&state->dev_mutex);
3753 if (rc) {
3754 printk(KERN_ERR "%s: mutex_lock interrupted.\n", __func__);
3755 return -ERESTARTSYS;
3756 }
3757
3758 /* not connected? exit */
3759 if (!test_bit(A2A_CONNECTED, state->flags)) {
3760 mutex_unlock(&state->dev_mutex);
3761 printk(KERN_ERR "%s: no a2a connection detected.\n", __func__);
3762 return -EINVAL;
3763 }
3764
3765 // busy?
3766 if (test_and_set_bit(WRITE_ACTIVE_BIT, state->flags)) {
3767 mutex_unlock(&state->dev_mutex);
3768 printk(KERN_ERR "%s: re-entrant call disallowed.\n", __func__);
3769 return -EINVAL;
3770 }
3771
3772 mutex_unlock(&state->dev_mutex);
3773
3774 /* copy to kernel buffer */
3775 //hdr.preamble = A2A_DGRAM_PREAMBLE;
3776 //hdr.len = count;
3777 //hdr.cksum = 0;
3778 ///* header */
3779 //if (copy_from_user(state->a2a_wr_buf, &hdr, sizeof(hdr))) {
3780 // rc = -EFAULT;
3781 // mutex_unlock(&state->dev_mutex);
3782 // goto err0;
3783 //}
3784 /* data */
3785 if (copy_from_user(state->a2a_wr_buf/*+sizeof(hdr)*/, buf, count)) {
3786 rc = -EFAULT;
3787 goto err0;
3788 }
3789 /* init a2a write ptr */
3790 state->a2a_wp = state->a2a_wr_buf;
3791
3792 wr_count = 0;
3793 miss_count = 0;
3794 elt_bufsize = 0;
3795 do {
3796 /* read comm status */
3797 reg_desc_comm_status = &a6_register_desc_arr[63];
3798 memset(vals, 0, sizeof(vals));
3799 rc = a6_i2c_read_reg(state->i2c_dev, reg_desc_comm_status->id,
3800 reg_desc_comm_status->num_ids, vals);
3801 if (rc < 0) {
3802 printk(KERN_ERR "%s: error reading reg: %s, id: 0x%x\n",
3803 __func__, reg_desc_comm_status->debug_name, reg_desc_comm_status->id[0]);
3804 goto err0;
3805 }
3806
3807 if (!(vals[0] & TS2_I2C_COMM_STATUS_TX_EMPTY)) {
3808 if (++miss_count > A2A_TX_MISS_THRESHOLD) {
3809 if (test_bit(A2A_CONNECTED, state->flags)) {
3810 continue;
3811 }
3812 else {
3813 break;
3814 }
3815 }
3816 continue;
3817 }
3818
3819 /* write tx data */
3820 reg_desc_comm_rxtx = &a6_register_desc_arr[64];
3821 if (!elt_bufsize) {
3822 if (a6_t2s_dup_correct) {
3823 elt_bufsize = 2;
3824 sprintf(elt_buf, "%02x", *state->a2a_wp);
3825 elt_buf[0] |= 0x80;
3826 }
3827 else {
3828 elt_bufsize = 1;
3829 elt_buf[0] = *state->a2a_wp;
3830 }
3831 elt_bufp = elt_buf;
3832 }
3833 rc = a6_i2c_write_reg(state->i2c_dev, reg_desc_comm_rxtx->id,
3834 reg_desc_comm_rxtx->num_ids, elt_bufp);
3835 if (rc < 0) {
3836 printk(KERN_ERR "%s: error writing reg: %s, id: 0x%x\n",
3837 __func__, reg_desc_comm_rxtx->debug_name, reg_desc_comm_rxtx->id[0]);
3838 rc = -EIO;
3839 goto err0;
3840 }
3841 elt_bufp++;
3842 elt_bufsize--;
3843
3844 if (!elt_bufsize) {
3845 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: written byte: %d successfully.\n",
3846 __func__, wr_count);
3847 state->a2a_wp++;
3848 wr_count++;
3849 }
3850 } while (wr_count < count);
3851
3852 if (!wr_count) {
3853 printk(KERN_ERR "%s: tx failed; A2A connection terminated.\n",
3854 __func__);
3855 rc = -EIO;
3856 goto err0;
3857 }
3858 else {
3859 long diff_time;
3860 rc = wr_count;
3861 diff_time = (long)jiffies - (long)start_time;
3862 printk(KERN_ERR "%s: elapsed time: %ld ms; count: %u\n", __func__,
3863 diff_time * 1000/HZ, wr_count);
3864 }
3865
3866
3867err0:
3868 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: exit\n", __func__);
3869 clear_bit(WRITE_ACTIVE_BIT, state->flags);
3870 return rc;
3871}
3872
3873static unsigned int a6_poll(struct file* file, struct poll_table_struct* wait)
3874{
3875 unsigned int mask = 0;
3876
3877 return mask;
3878}
3879
3880struct file_operations a6_fops = {
3881 .owner = THIS_MODULE,
3882 .read = a6_read,
3883 .write = a6_write,
3884 .poll = a6_poll,
3885 .unlocked_ioctl = a6_ioctl,
3886 .open = a6_open,
3887 .release = a6_close,
3888};
3889
3890/*
3891 * a6 interrupt handler
3892 */
3893static irqreturn_t a6_irq(int irq, void *dev_id)
3894{
3895 struct a6_device_state* state = (struct a6_device_state *)dev_id;
3896
3897 a6_tp_irq_count++;
3898#if defined PROFILE_USAGE
3899 /*
3900 if (true == reset_active) {
3901 diff_time = (long)jiffies - (long)start_time;
3902 reset_active = false;
3903 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "A6_IRQ toggle post power-cycle after: %d ms\n",
3904 diff_time*1000/HZ);
3905 }
3906 */
3907#endif
3908
3909 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: entry.\n", __func__);
3910
3911 if (test_bit(IS_SUSPENDED, state->flags)) {
3912 set_bit(INT_PENDING, state->flags);
3913 } else {
3914 queue_work(state->ka6d_workqueue, &state->a6_irq_work);
3915 }
3916
3917 return IRQ_HANDLED;
3918}
3919
3920void a6_irq_work_handler(struct work_struct *work)
3921{
3922 struct a6_device_state* state =
3923 container_of(work, struct a6_device_state, a6_irq_work);
3924 struct a6_register_desc *reg_desc_status3, *reg_desc_status2;
3925 uint8_t vals[id_size], reg_val_status3 = 0, reg_val_status2 = 0;
3926 bool charge_source_changed = false;
3927 bool battery_changed = false;
3928 int32_t ret = 0;
3929 char *envp[] = {
3930 [0] = "A6_ACTION=EMERGENCY_RESET_NOTIFY",
3931 [1] = NULL,
3932 [2] = "A6_ACTION=LOG_THRESHOLD_NOTIFY",
3933 [3] = NULL,
3934 [4] = "A6_ACTION=CHARGE_SOURCE_NOTIFY",
3935 [5] = NULL,
3936 [6] = "A6_ACTION=PERCENT_LOW_WARN1_NOTIFY",
3937 [7] = NULL,
3938 [8] = "A6_ACTION=PERCENT_LOW_WARN2_NOTIFY",
3939 [9] = NULL,
3940 [10] = "A6_ACTION=PECENT_LOW_CRIT_NOTIFY",
3941 [11] = NULL,
3942 [12] = "A6_ACTION=VOLTAGE_LOW_CRIT_NOTIFY",
3943 [13] = NULL,
3944 [14] = "A6_ACTION=TEMP_LOW_CRIT_NOTIFY",
3945 [15] = NULL,
3946 [16] = "A6_ACTION=TEMP_HIGH_CRIT_NOTIFY",
3947 [17] = NULL,
3948 [18] = "A6_ACTION=A2A_CONNECT_NOTIFY",
3949 [19] = NULL
3950 };
3951
3952 // block irq processing while a6 fw flashing is in progress because i2c requests
3953 // will fail anyway and we dont' want to fiddle with SBW_WKUP while flashing is
3954 // in progress...
3955
3956 // critsec for manipulating flags
3957 mutex_lock(&state->dev_mutex);
3958
3959 // busy?
3960 while (test_and_set_bit(DEVICE_BUSY_BIT, state->flags)) {
3961 // yes: are we in bootload phase?
3962 if (!test_bit(BOOTLOAD_ACTIVE_BIT, state->flags)) {
3963 // no: so go ahead and allow concurrent i2c ops (these are
3964 // synchronized separately to allow priority based execution).
3965 break;
3966 }
3967
3968 // in bootload phase: get on a waitq
3969 mutex_unlock(&state->dev_mutex);
3970 printk(KERN_ERR "%s: about to wait for device non-busy...\n", __func__);
3971
3972 // bootload bit set? wait to be cleared (at least 5 mins: in jiffies)
3973 ret = wait_event_interruptible_timeout(state->dev_busyq,
3974 !test_bit(BOOTLOAD_ACTIVE_BIT, state->flags), 300*HZ);
3975 if (!ret) {
3976 printk(KERN_ERR "%s: wait on device busy timed-out/interrupted\n", __func__);
3977 // reset busy state
3978 clear_bit(BOOTLOAD_ACTIVE_BIT, state->flags);
3979 clear_bit(DEVICE_BUSY_BIT, state->flags);
3980 // and continue...
3981 }
3982
3983 // we're about to manipulate flags again: acquire critsec
3984 mutex_lock(&state->dev_mutex);
3985 }
3986
3987 /* increment busy refcount */
3988 state->busy_count++;
3989
3990 // done with flags: exit critsec
3991 mutex_unlock(&state->dev_mutex);
3992
3993 /* determine irq cause */
3994 reg_desc_status3 = &a6_register_desc_arr[7];
3995 reg_desc_status2 = &a6_register_desc_arr[6];
3996
3997 /* (1) read int_status3: emergency reset and charge-source change */
3998 memset(vals, 0, sizeof(vals));
3999 ret = a6_i2c_read_reg(state->i2c_dev, reg_desc_status3->id, reg_desc_status3->num_ids, vals);
4000 if (ret < 0) {
4001 printk(KERN_ERR "%s: error reading reg: %s, id: 0x%x\n",
4002 __func__, reg_desc_status3->debug_name, reg_desc_status3->id[0]);
4003 goto err0;
4004 }
4005 reg_val_status3 = vals[0];
4006
4007 /* (2) read int_status2: other irq causes */
4008 memset(vals, 0, sizeof(vals));
4009 ret = a6_i2c_read_reg(state->i2c_dev, reg_desc_status2->id, reg_desc_status2->num_ids, vals);
4010 if (ret < 0) {
4011 printk(KERN_ERR "%s: error reading reg: %s, id: 0x%x\n",
4012 __func__, reg_desc_status2->debug_name, reg_desc_status2->id[0]);
4013 goto err0;
4014 }
4015 reg_val_status2 = vals[0];
4016
4017 /* (3) now clear all status bits: this "releases" the irq line early */
4018 if (reg_val_status3) {
4019 vals[0] = reg_val_status3;
4020 ret = a6_i2c_write_reg(state->i2c_dev, reg_desc_status3->id, reg_desc_status3->num_ids, vals);
4021 if (ret < 0) {
4022 printk(KERN_ERR "%s: error writing reg: %s, id: 0x%x\n",
4023 __func__, reg_desc_status3->debug_name, reg_desc_status3->id[0]);
4024 goto err0;
4025 }
4026 }
4027 if (reg_val_status2) {
4028 vals[0] = reg_val_status2;
4029 ret = a6_i2c_write_reg(state->i2c_dev, reg_desc_status2->id, reg_desc_status2->num_ids, vals);
4030 if (ret < 0) {
4031 printk(KERN_ERR "%s: error writing reg: %s, id: 0x%x\n",
4032 __func__, reg_desc_status3->debug_name, reg_desc_status3->id[0]);
4033 goto err0;
4034 }
4035 }
4036
4037 /* (4) process emergency reset and charge-source changes...*/
4038 if (reg_val_status3) {
4039 /* emergency reset? */
4040 if (reg_val_status3 & TS2_I2C_INT_3_RESET) {
4041 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: emergency reset detected.\n",
4042 __func__);
4043
4044 /* Send uevent */
4045 kobject_uevent_env(&state->i2c_dev->dev.kobj, KOBJ_CHANGE, &envp[0]);
4046 /* this condition overrides all others and we can probably skip
4047 resetting the status bits */
4048 goto err0;
4049 }
4050
4051 /* a2a connect change? */
4052 if (reg_val_status3 & TS2_I2C_INT_3_A2A_CONNECT_CHANGE) {
4053 struct a6_register_desc *reg_desc_charger;
4054 uint8_t chg_vals[id_size];
4055
4056 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: a2a connect change detected.\n",
4057 __func__);
4058 printk(KERN_ERR "%s: a2a connect change detected.\n", __func__);
4059 reg_desc_charger = &a6_register_desc_arr[31];
4060 memset(chg_vals, 0, sizeof(chg_vals));
4061 if (a6_i2c_read_reg(state->i2c_dev, reg_desc_charger->id,
4062 reg_desc_charger->num_ids, chg_vals) < 0) {
4063 printk(KERN_ERR "%s: error reading reg: %s, id: 0x%x\n",
4064 __func__, reg_desc_charger->debug_name,
4065 reg_desc_charger->id[0]);
4066 }
4067 else {
4068 if (chg_vals[0] & TS2_I2C_FLAGS_2_A2A_CONNECT) {
4069 set_bit(A2A_CONNECTED, state->flags);
4070 }
4071 else {
4072 clear_bit(A2A_CONNECTED, state->flags);
4073 }
4074 /* Send uevent */
4075 kobject_uevent_env(&state->i2c_dev->dev.kobj, KOBJ_CHANGE, &envp[18]);
4076 }
4077 }
4078
4079 /* charger-source change? */
4080 if (reg_val_status3 & TS2_I2C_INT_3_FLAGS_CHANGE) {
4081 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: charger-source change detected.\n",
4082 __func__);
4083
4084 /* next, unblock task on charger_source_notify node */
4085 //sysfs_notify_dirent(state->notify_nodes[DIRENT_CHG_SRC_NOTIFY]);
4086 /* Send uevent */
4087 kobject_uevent_env(&state->i2c_dev->dev.kobj, KOBJ_CHANGE, &envp[4]);
4088 charge_source_changed = true;
4089 }
4090
4091 /* log threshold change? */
4092 if (reg_val_status3 & TS2_I2C_INT_3_LOG) {
4093 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: log threshold detected.\n",
4094 __func__);
4095
4096 /* Send uevent */
4097 kobject_uevent_env(&state->i2c_dev->dev.kobj, KOBJ_CHANGE, &envp[2]);
4098 }
4099 }
4100
4101 /* (5) process other irq causes... */
4102 if (reg_val_status2) {
4103 /* battery low critical? */
4104 if (reg_val_status2 & TS2_I2C_INT_2_BAT_RARC_CRIT) {
4105 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: battery low critical detected.\n",
4106 __func__);
4107
4108 /* Send uevent */
4109 kobject_uevent_env(&state->i2c_dev->dev.kobj, KOBJ_CHANGE, &envp[10]);
4110 battery_changed = true;
4111 }
4112
4113 /* battery voltage low critical? */
4114 if (reg_val_status2 & TS2_I2C_INT_2_BAT_VOLT_LOW) {
4115 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: battery voltage low critical detected.\n",
4116 __func__);
4117
4118 /* Send uevent */
4119 kobject_uevent_env(&state->i2c_dev->dev.kobj, KOBJ_CHANGE, &envp[12]);
4120 battery_changed = true;
4121 }
4122
4123 /* battery temp high critical? */
4124 if (reg_val_status2 & TS2_I2C_INT_2_BAT_TEMP_HIGH) {
4125 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: battery temp high critical detected.\n",
4126 __func__);
4127
4128 /* Send uevent */
4129 kobject_uevent_env(&state->i2c_dev->dev.kobj, KOBJ_CHANGE, &envp[16]);
4130 }
4131
4132 /* battery temp low critical? */
4133 if (reg_val_status2 & TS2_I2C_INT_2_BAT_TEMP_LOW) {
4134 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: battery temp low critical detected.\n",
4135 __func__);
4136
4137 /* Send uevent */
4138 kobject_uevent_env(&state->i2c_dev->dev.kobj, KOBJ_CHANGE, &envp[14]);
4139 }
4140
4141 /* battery low percent warn2? */
4142 if (reg_val_status2 & TS2_I2C_INT_2_BAT_RARC_LOW2) {
4143 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: battery low percent warn2 detected.\n",
4144 __func__);
4145
4146 /* Send uevent */
4147 kobject_uevent_env(&state->i2c_dev->dev.kobj, KOBJ_CHANGE, &envp[8]);
4148 battery_changed = true;
4149 }
4150
4151 /* battery low percent warn1? */
4152 if (reg_val_status2 & TS2_I2C_INT_2_BAT_RARC_LOW1) {
4153 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: battery low percent warn1 detected.\n",
4154 __func__);
4155
4156 /* Send uevent */
4157 kobject_uevent_env(&state->i2c_dev->dev.kobj, KOBJ_CHANGE, &envp[6]);
4158 battery_changed = true;
4159 }
4160 }
4161
4162err0:
4163 /* decrement busy refcount */
4164 if (state->busy_count)
4165 state->busy_count--;
4166 if (!state->busy_count)
4167 clear_bit(DEVICE_BUSY_BIT, state->flags);
4168
4169 if (charge_source_changed) {
4170 a6_dock_update_state(state);
4171 }
4172 if (state->plat_data->power_supply_connected == 1 && batt_state != NULL) {
4173 if (battery_changed) {
4174 power_supply_changed(&a6_fish_power_supplies[0]);
4175 }
4176 if (charge_source_changed) {
4177 power_supply_changed(&a6_fish_power_supplies[1]);
4178 power_supply_changed(&a6_fish_power_supplies[2]);
4179#ifdef CONFIG_A6_ENABLE_DOCK_PS
4180 power_supply_changed(&a6_fish_power_supplies[3]);
4181#endif
4182 a6_update_connected_ps();
4183 }
4184 }
4185
4186 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: Visited\n", __func__);
4187}
4188
4189
4190#ifdef A6_PQ
4191int32_t a6_stop_ai_dispatch_task(struct a6_device_state* state)
4192{
4193 int32_t rc = 0;
4194
4195 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: entered.\n", __func__);
4196 // critsec for manipulating flags
4197 rc = mutex_lock_interruptible(&state->dev_mutex);
4198 if (rc) {
4199 printk(KERN_ERR "%s: mutex_lock interrupted\n", __func__);
4200 return -ERESTARTSYS;
4201 }
4202 // stopping during a start? fail
4203 if (test_bit(STARTING_AID_TASK, state->flags)) {
4204 printk(KERN_ERR "%s: aid task not fully started. failing op.\n", __func__);
4205 rc = -EBUSY;
4206 mutex_unlock(&state->dev_mutex);
4207 goto err0;
4208 }
4209
4210 // stopping during a stop? fail
4211 if (test_bit(KILLING_AID_TASK, state->flags)) {
4212 printk(KERN_ERR "%s: aid task being stopped. failing op.\n", __func__);
4213 rc = -EBUSY;
4214 mutex_unlock(&state->dev_mutex);
4215 goto err0;
4216 }
4217
4218 // task never started? fail
4219 if (!state->ai_dispatch_task) {
4220 printk(KERN_ERR "%s: no aid task. failing op.\n", __func__);
4221 rc = -EPERM;
4222 mutex_unlock(&state->dev_mutex);
4223 goto err0;
4224 }
4225
4226 // transition to quiesced state: stops accepting new requests
4227 set_bit(IS_QUIESCED, state->flags);
4228 // declare intent to kill ai dispatch task
4229 set_bit(KILLING_AID_TASK, state->flags);
4230 // exit critsec
4231 mutex_unlock(&state->dev_mutex);
4232
4233 // kick task if asleep
4234 complete(&state->aq_enq_complete);
4235
4236 // wait for ai dispatch task exit
4237 rc = wait_for_completion_interruptible(&state->aid_exit_complete);
4238 if (rc < 0) {
4239 printk(KERN_ERR "%s: wait for ai dispatch task exit interrupted.\n",
4240 __func__);
4241 }
4242
4243 // critsec for manipulating flags
4244 rc = mutex_lock_interruptible(&state->dev_mutex);
4245 if (rc) {
4246 printk(KERN_ERR "%s: mutex_lock interrupted(1)\n", __func__);
4247 return -ERESTARTSYS;
4248 }
4249 // ai dispatch task exited (assume it did if we get interrupted): reset state
4250 clear_bit(KILLING_AID_TASK, state->flags);
4251 state->ai_dispatch_task = NULL;
4252 // exit critsec
4253 mutex_unlock(&state->dev_mutex);
4254
4255
4256err0:
4257 return rc;
4258}
4259
4260int32_t a6_start_ai_dispatch_task(struct a6_device_state* state)
4261{
4262 int32_t rc = 0;
4263 pid_t ai_dispatch_pid;
4264
4265 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: entered.\n", __func__);
4266
4267 // critsec for manipulating flags
4268 rc = mutex_lock_interruptible(&state->dev_mutex);
4269 if (rc) {
4270 printk(KERN_ERR "%s: mutex_lock interrupted\n", __func__);
4271 return -ERESTARTSYS;
4272 }
4273 // starting during a start? fail
4274 if (test_bit(STARTING_AID_TASK, state->flags)) {
4275 printk(KERN_ERR "%s: aid task not fully started. failing op.\n", __func__);
4276 rc = -EBUSY;
4277 mutex_unlock(&state->dev_mutex);
4278 goto err0;
4279 }
4280
4281 // starting during a stop? fail
4282 if (test_bit(KILLING_AID_TASK, state->flags)) {
4283 printk(KERN_ERR "%s: aid task being stopped. failing op.\n", __func__);
4284 rc = -EBUSY;
4285 mutex_unlock(&state->dev_mutex);
4286 goto err0;
4287 }
4288
4289 // task never stopped? fail
4290 if (state->ai_dispatch_task) {
4291 printk(KERN_ERR "%s: aid task exists. failing op.\n", __func__);
4292 rc = -EPERM;
4293 mutex_unlock(&state->dev_mutex);
4294 goto err0;
4295 }
4296
4297 // declare intent to start ai dispatch task
4298 set_bit(STARTING_AID_TASK, state->flags);
4299 // exit critsec
4300 mutex_unlock(&state->dev_mutex);
4301
4302
4303 // create ai dispatcher task...
4304 ai_dispatch_pid = kernel_thread(ai_dispatch_thread_fn, state,
4305 CLONE_KERNEL);
4306 if (ai_dispatch_pid < 0) {
4307 printk(KERN_ERR "%s: failed to create ai dispatcher task.\n", __func__);
4308 rc = -EIO;
4309 goto err0;
4310 }
4311
4312 rc = mutex_lock_interruptible(&state->dev_mutex);
4313 if (rc) {
4314 printk(KERN_ERR "%s: mutex_lock interrupted(1)\n", __func__);
4315 return -ERESTARTSYS;
4316 }
4317 // retrieve worker task struct
4318 state->ai_dispatch_task = get_pid_task(find_get_pid(ai_dispatch_pid), PIDTYPE_PID);
4319 ASSERT(state->ai_dispatch_task);
4320
4321 // transition to active state: start accepting new requests
4322 clear_bit(IS_QUIESCED, state->flags);
4323 // ai dispatch task started: reset state
4324 clear_bit(STARTING_AID_TASK, state->flags);
4325 // exit critsec
4326 mutex_unlock(&state->dev_mutex);
4327
4328err0:
4329 return rc;
4330}
4331#endif // A6_PQ
4332
4333void a6_force_wake_work_handler(struct work_struct *work)
4334{
4335 struct a6_device_state* state =
4336 container_of(work, struct a6_device_state, a6_force_wake_work);
4337 struct a6_wake_ops* wake_ops = (struct a6_wake_ops*)state->plat_data->wake_ops;
4338 long diff_time;
4339
4340 diff_time = (long)jiffies - (long)start_last_a6_activity;
4341 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: forcing sleep after: %ld ms\n",
4342 __func__, diff_time * 1000/HZ);
4343
4344 start_last_a6_activity = 0;
4345
4346 // force A6 sleep and switch back to periodic wake...
4347 // * timer may be scheduled just after we clear FORCE_WAKE_ACTIVE_BIT
4348 // and hence will result in the callback being invoked with
4349 // FORCE_WAKE_ACTIVE_BIT cleared. We just ignore this case...
4350 mutex_lock(&state->a6_force_wake_mutex);
4351 if (!test_bit(DEVICE_BUSY_BIT, state->flags)) {
4352 if (test_bit(FORCE_WAKE_ACTIVE_BIT, state->flags)) {
4353 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR,
4354 "%s: disabling force_wake and enabling periodic_wake\n",
4355 __func__);
4356 /* force A6 sleep */
4357 if (wake_ops->force_sleep) {
4358 wake_ops->force_sleep(wake_ops->data);
4359 }
4360 /* enable periodic a6 wake (if defined) */
4361 if (wake_ops->enable_periodic_wake) {
4362 wake_ops->enable_periodic_wake(wake_ops->data);
4363 }
4364 /* now we are ready to clear FORCE_WAKE_ACTIVE_BIT */
4365 clear_bit(FORCE_WAKE_ACTIVE_BIT, state->flags);
4366 }
4367 }
4368 mutex_unlock(&state->a6_force_wake_mutex);
4369}
4370
4371
4372// timer callback used to force sleep after a force wake
4373void a6_force_wake_timer_callback(ulong data)
4374{
4375 struct a6_device_state* state = (struct a6_device_state*)data;
4376 int32_t rc;
4377
4378 rc = queue_work(state->ka6d_fw_workqueue, &state->a6_force_wake_work);
4379 if (!rc) {
4380 printk(KERN_ERR "**** %s: failed queueing force_wake work item.\n", __func__);
4381 }
4382}
4383
4384static int a6_pmem_open(struct inode *inode, struct file *file)
4385{
4386 struct a6_device_state* state;
4387
4388 /* get device */
4389 state = container_of(file->f_op, struct a6_device_state, pmem_fops);
4390
4391 /* Allow only read. */
4392 if ((file->f_mode & (FMODE_READ|FMODE_WRITE)) != FMODE_READ) {
4393 return -EINVAL;
4394 }
4395
4396 /* check if it is in use */
4397 if (test_and_set_bit(IS_OPENED, state->flags)) {
4398 return -EBUSY;
4399 }
4400
4401 /* attach private data */
4402 file->private_data = state;
4403 return 0;
4404}
4405
4406static int a6_pmem_close(struct inode *inode, struct file *file)
4407{
4408 struct a6_device_state* state = (struct a6_device_state*) file->private_data;
4409
4410 /* mark it as unused */
4411 clear_bit(IS_OPENED, state->flags);
4412 return 0;
4413}
4414
4415static ssize_t a6_pmem_read(struct file *file, char __user *buf, size_t count, loff_t *ppos )
4416{
4417
4418 ssize_t rc = 0;
4419 struct a6_device_state* state;
4420
4421 A6_DPRINTK(A6_DEBUG_VERBOSE, KERN_ERR, "%s: enter\n", __func__);
4422
4423 /* input validations */
4424 if (!count) {
4425 return -EINVAL;
4426 }
4427
4428 /* get state */
4429 state = container_of(file->f_op, struct a6_device_state, fops);
4430 rc = ttf_image_read(buf, count, ppos);
4431
4432 return rc;
4433}
4434
4435struct file_operations a6_pmem_fops = {
4436 .owner = THIS_MODULE,
4437 .read = a6_pmem_read,
4438 .open = a6_pmem_open,
4439 .release = a6_pmem_close,
4440};
4441
4442static int a6_fish_battery_get_percent(struct device *dev)
4443{
4444 int temp_val = 0;
4445
4446 a6_reg_get (dev, A6_REG_TS2_I2C_BAT_RARC, &temp_val);
4447
4448#if defined(CONFIG_A6_BATTERY_SCALED_MIN) && CONFIG_A6_BATTERY_SCALED_MIN != 0
4449 temp_val = (temp_val - CONFIG_A6_BATTERY_SCALED_MIN) * 100
4450 / (100 - CONFIG_A6_BATTERY_SCALED_MIN);
4451 if (temp_val < 0) temp_val = 0;
4452#endif
4453
4454 return temp_val;
4455}
4456
4457static unsigned a6_calc_connected_ps(void)
4458{
4459 struct power_supply *psy;
4460 struct a6_device_state *state;
4461 unsigned int temp_val = 0;
4462 unsigned connected = 0;
4463
4464 psy = &a6_fish_power_supplies[0];
4465
4466 if (!(psy->dev)) {
4467 printk(KERN_ERR "%s: psy->dev is NULL\n", __func__);
4468 return 0;
4469 }
4470 if (!(psy->dev->parent)) {
4471 printk(KERN_ERR "%s: psy->dev->parent is NULL\n", __func__);
4472 return 0;
4473 }
4474
4475 state = (struct a6_device_state*)dev_get_drvdata(psy->dev->parent);
4476
4477 a6_reg_get (psy->dev->parent, A6_REG_TS2_I2C_FLAGS_2, &temp_val);
4478
4479 if (state->otg_chg_type == USB_CHG_TYPE__WALLCHARGER) {
4480 connected |= MAX8903B_CONNECTED_PS_AC;
4481 }
4482
4483 if (state->otg_chg_type == USB_CHG_TYPE__SDP
4484 && (temp_val & TS2_I2C_FLAGS_2_WIRED_CHARGE)) {
4485 /* NOTE: USB will not show as connected if DOCK is connected */
4486 connected |= MAX8903B_CONNECTED_PS_USB;
4487 }
4488
4489 if(temp_val & TS2_I2C_FLAGS_2_PUCK_CHARGE) {
4490 connected |= MAX8903B_CONNECTED_PS_DOCK;
4491 }
4492
4493 return connected;
4494}
4495
4496static void a6_update_connected_ps()
4497{
4498 unsigned connected = a6_calc_connected_ps();
4499
4500 printk(KERN_INFO "%s: ac=%d usb=%d dock=%d\n", __func__,
4501 (connected & MAX8903B_CONNECTED_PS_AC) ? 1 : 0,
4502 (connected & MAX8903B_CONNECTED_PS_USB) ? 1 : 0,
4503 (connected & MAX8903B_CONNECTED_PS_DOCK) ? 1 : 0);
4504
4505 max8903b_set_connected_ps(connected);
4506 a6_last_ps_connect = (long)jiffies;
4507}
4508
4509static int a6_fish_power_get_property(struct power_supply *psy,
4510 enum power_supply_property psp,
4511 union power_supply_propval *val)
4512{
4513 unsigned connected;
4514
4515 switch (psp) {
4516 case POWER_SUPPLY_PROP_ONLINE:
4517 connected = a6_calc_connected_ps();
4518
4519 if (
4520 (psy->type == POWER_SUPPLY_TYPE_MAINS
4521 && (connected & MAX8903B_CONNECTED_PS_AC)
4522#ifdef CONFIG_A6_ENABLE_DOCK_PS
4523 && !(connected & MAX8903B_CONNECTED_PS_DOCK)
4524 && !strcmp(psy->name, "ac")
4525#endif
4526 )
4527 ||
4528 (psy->type == POWER_SUPPLY_TYPE_MAINS
4529 && (connected & MAX8903B_CONNECTED_PS_DOCK)
4530#ifdef CONFIG_A6_ENABLE_DOCK_PS
4531 && !strcmp(psy->name, "dock")
4532#endif
4533 )
4534 ||
4535 (psy->type == POWER_SUPPLY_TYPE_USB
4536 && (connected & MAX8903B_CONNECTED_PS_USB)
4537 && !(connected & MAX8903B_CONNECTED_PS_DOCK)
4538 )
4539 ) {
4540 val->intval = 1;
4541 } else {
4542 val->intval = 0;
4543 }
4544 break;
4545 default:
4546 return -EINVAL;
4547 }
4548
4549 return 0;
4550}
4551
4552
4553#define A6_BATT_STATS_DELAY (msecs_to_jiffies (15*1000))
4554static int a6_fish_battery_get_property(struct power_supply *psy,
4555 enum power_supply_property psp,
4556 union power_supply_propval *val)
4557{
4558 int temp_val = 0;
4559 unsigned connected;
4560
4561 switch (psp) {
4562 case POWER_SUPPLY_PROP_STATUS:
4563 if (a6_fish_battery_get_percent(psy->dev->parent) == 100) {
4564 val->intval = POWER_SUPPLY_STATUS_FULL;
4565 } else if (a6_last_ps_connect &&
4566 jiffies > a6_last_ps_connect + A6_BATT_STATS_DELAY) {
4567 a6_reg_get (psy->dev->parent,
4568 A6_REG_TS2_I2C_BAT_AVG_CUR_LSB_MSB, &temp_val);
4569 if (temp_val > 0) {
4570 val->intval = POWER_SUPPLY_STATUS_CHARGING;
4571 } else {
4572 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
4573 }
4574 } else {
4575 connected = a6_calc_connected_ps();
4576 if (connected && !(connected == MAX8903B_CONNECTED_PS_USB)) {
4577 val->intval = POWER_SUPPLY_STATUS_CHARGING;
4578 } else {
4579 val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
4580 }
4581 }
4582 break;
4583 case POWER_SUPPLY_PROP_HEALTH:
4584#if 0
4585 /* NOTE: *_BAT_STATUS not supported by a6_reg_get yet */
4586 a6_reg_get(psy->dev->parent, A6_REG_TS2_I2C_BAT_STATUS, &temp_uval);
4587#endif
4588 // TODO: parse temps and set OVERHEAT, parse "age" and set DEAD */
4589
4590 val->intval = POWER_SUPPLY_HEALTH_GOOD;
4591 break;
4592 case POWER_SUPPLY_PROP_PRESENT:
4593 val->intval = 1;
4594 break;
4595 case POWER_SUPPLY_PROP_TECHNOLOGY:
4596 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
4597 break;
4598 case POWER_SUPPLY_PROP_CAPACITY:
4599 val->intval = a6_fish_battery_get_percent(psy->dev->parent);
4600 break;
4601 case POWER_SUPPLY_PROP_CURRENT_NOW:
4602 a6_reg_get(psy->dev->parent,
4603 A6_REG_TS2_I2C_BAT_CUR_LSB_MSB, &temp_val);
4604 val->intval = temp_val;
4605 break;
4606 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
4607 a6_reg_get (psy->dev->parent,
4608 A6_REG_TS2_I2C_BAT_VOLT_LSB_MSB, &temp_val);
4609 val->intval = temp_val;
4610 break;
4611 case POWER_SUPPLY_PROP_TEMP:
4612 a6_reg_get (psy->dev->parent,
4613 A6_REG_TS2_I2C_BAT_TEMP_LSB_MSB, &temp_val);
4614 val->intval = temp_val;
4615 break;
4616 case POWER_SUPPLY_PROP_CHARGE_FULL:
4617 a6_reg_get (psy->dev->parent,
4618 A6_REG_TS2_I2C_BAT_FULL40_LSB_MSB, &temp_val);
4619 val->intval = temp_val;
4620 break;
4621 case POWER_SUPPLY_PROP_CHARGE_NOW:
4622 a6_reg_get (psy->dev->parent,
4623 A6_REG_TS2_I2C_BAT_COULOMB_LSB_MSB, &temp_val);
4624 val->intval = temp_val;
4625 break;
4626 default:
4627 return -EINVAL;
4628 }
4629
4630 return 0;
4631}
4632
4633void a6_charger_event (enum chg_type otg_chg_type)
4634{
4635 if (batt_state) {
4636 batt_state->otg_chg_type = otg_chg_type;
4637
4638 power_supply_changed(&a6_fish_power_supplies[1]);
4639 power_supply_changed(&a6_fish_power_supplies[2]);
4640#ifdef CONFIG_A6_ENABLE_DOCK_PS
4641 power_supply_changed(&a6_fish_power_supplies[3]);
4642#endif
4643 a6_update_connected_ps();
4644 }
4645 return;
4646}
4647EXPORT_SYMBOL (a6_charger_event);
4648
4649#define A6_BATT_HB_PERIOD (msecs_to_jiffies (5*60*1000))
4650#define A6_INIT_CONNECTED_PS_DELAY (msecs_to_jiffies (60*1000))
4651static void a6_battery_heartbeat(struct work_struct *a6_battery_work)
4652{
4653 int percent = 0;
4654
4655 struct delayed_work *temp_charge_work =
4656 container_of (a6_battery_work, struct delayed_work, work);
4657 struct a6_device_state* state =
4658 container_of(temp_charge_work, struct a6_device_state, charge_work);
4659
4660 if (state->stop_heartbeat)
4661 return;
4662
4663 if ( (percent = a6_fish_battery_get_percent(&state->i2c_dev->dev))
4664 != state->last_percent){
4665
4666 state->last_percent = percent;
4667 power_supply_changed(&a6_fish_power_supplies[0]);
4668 }
4669
4670 if (!state->stop_heartbeat)
4671 schedule_delayed_work(&state->charge_work,
4672 A6_BATT_HB_PERIOD);
4673}
4674
4675static void a6_init_connected_ps(struct work_struct *work)
4676{
4677 a6_update_connected_ps();
4678}
4679
4680static int a6_fish_battery_probe(struct a6_device_state *state)
4681{
4682 int i;
4683 int rc = 0;
4684 struct i2c_client *client = state->i2c_dev;
4685
4686 /* init power supplier framework */
4687 for (i = 0; i < ARRAY_SIZE(a6_fish_power_supplies); i++) {
4688
4689 rc = power_supply_register(&client->dev, &a6_fish_power_supplies[i]);
4690 if (rc)
4691 pr_err("%s: Failed to register power supply (%d)\n",
4692 __func__, rc);
4693 }
4694
4695 INIT_DELAYED_WORK(&state->charge_work, a6_battery_heartbeat);
4696 schedule_delayed_work(&state->charge_work, A6_BATT_HB_PERIOD);
4697
4698 INIT_DELAYED_WORK(&state->init_connected_ps_work, a6_init_connected_ps);
4699 schedule_delayed_work(&state->init_connected_ps_work, A6_INIT_CONNECTED_PS_DELAY);
4700
4701 return rc;
4702}
4703
4704
4705static int a6_fish_battery_remove(struct a6_device_state *state)
4706{
4707 int i;
4708
4709 state->stop_heartbeat = true;
4710 cancel_delayed_work_sync(&state->charge_work);
4711
4712 /* init power supplier framework */
4713 for (i = 0; i < ARRAY_SIZE(a6_fish_power_supplies); i++) {
4714 power_supply_unregister(&a6_fish_power_supplies[i]);
4715 }
4716
4717 return 0;
4718}
4719
4720static int a6_fish_battery_suspend (struct a6_device_state *state)
4721{
4722
4723 if (state->plat_data->power_supply_connected == 1 &&
4724 delayed_work_pending(&state->charge_work)) {
4725 state->stop_heartbeat = true;
4726 smp_mb();
4727 cancel_delayed_work_sync(&state->charge_work);
4728 }
4729
4730 return 0;
4731}
4732
4733static int a6_fish_battery_resume (struct a6_device_state *state)
4734{
4735 if (state->plat_data->power_supply_connected == 1) {
4736 state->stop_heartbeat = false;
4737 schedule_delayed_work(&state->charge_work,
4738 A6_BATT_HB_PERIOD);
4739
4740 power_supply_changed(&a6_fish_power_supplies[0]);
4741 }
4742 return 0;
4743}
4744
4745static ssize_t a6_dock_print_name(struct switch_dev *sdev, char *buf)
4746{
4747 bool docked = switch_get_state(sdev) != 0;
4748 return sprintf(buf, docked ? "DESK\n" : "None\n");
4749}
4750
4751static void a6_dock_update_state(struct a6_device_state *state)
4752{
4753 unsigned int value, dock;
4754
4755 if (state->dock_switch == NULL) {
4756 return;
4757 }
4758
4759 a6_reg_get (&state->i2c_dev->dev, A6_REG_TS2_I2C_FLAGS_2, &value);
4760
4761 if (a6_disable_dock_switch) {
4762 dock = 0;
4763 } else {
4764 dock = value & TS2_I2C_FLAGS_2_PUCK ? 1 : 0;
4765 }
4766 switch_set_state(state->dock_switch, dock);
4767}
4768
4769static int param_set_disable_dock_switch(const char *val,
4770 struct kernel_param *kp)
4771{
4772 struct a6_device_state *state;
4773
4774 state = batt_state;
4775
4776 param_set_int(val, kp);
4777 a6_dock_update_state(state);
4778
4779 return 0;
4780}
4781
4782static int a6_dock_probe(struct a6_device_state *state)
4783{
4784 int ret;
4785
4786 state->dock_switch = kzalloc(sizeof(struct switch_dev), GFP_KERNEL);
4787 if (state->dock_switch == NULL) {
4788 return -ENOMEM;
4789 }
4790
4791 state->dock_switch->name = "dock";
4792 state->dock_switch->print_name = a6_dock_print_name;
4793
4794 ret = switch_dev_register(state->dock_switch);
4795 if (ret < 0) {
4796 kfree(state->dock_switch);
4797 state->dock_switch = NULL;
4798 return ret;
4799 }
4800
4801 a6_dock_update_state(state);
4802
4803 return 0;
4804}
4805
4806static void a6_dock_remove(struct a6_device_state *state)
4807{
4808 switch_dev_unregister(state->dock_switch);
4809 kfree(state->dock_switch);
4810 state->dock_switch = NULL;
4811}
4812
4813/******************************************************************************
4814* a6_i2c_probe()
4815******************************************************************************/
4816static int a6_i2c_probe(struct i2c_client *client, const struct i2c_device_id *dev_id)
4817{
4818 int rc = 0;
4819 struct a6_device_state* state = NULL;
4820 struct a6_platform_data* plat_data = client->dev.platform_data;
4821 struct a6_wake_ops *wake_ops = (struct a6_wake_ops *) plat_data->wake_ops;
4822
4823 if (plat_data == NULL) {
4824 /* should this be -ENODEV ? TODO */
4825 return ENODEV;
4826 }
4827
4828 state = kzalloc(sizeof(struct a6_device_state), GFP_KERNEL);
4829 if(!state) {
4830 /* should this be -ENOMEM ? TODO */
4831 return ENOMEM;
4832 }
4833
4834 state->a2a_rd_buf = kzalloc(A2A_RD_BUFF_SIZE, GFP_KERNEL);
4835 if(!state->a2a_rd_buf) {
4836 rc = -ENOMEM;
4837 goto err0;
4838 }
4839 state->a2a_wr_buf = kzalloc(A2A_WR_BUFF_SIZE, GFP_KERNEL);
4840 if(!state->a2a_wr_buf) {
4841 rc = -ENOMEM;
4842 goto err1;
4843 }
4844
4845 // store i2c client device in state
4846 state->i2c_dev = client;
4847
4848 // set platform data in device-specific driver data
4849 state->plat_data = plat_data;
4850
4851 mutex_init(&state->dev_mutex);
4852#ifdef A6_PQ
4853 init_completion(&state->aq_enq_complete);
4854 init_completion(&state->aid_exit_complete);
4855 mutex_init(&state->aq_mutex);
4856 INIT_LIST_HEAD(&state->aq_head);
4857#endif // A6_PQ
4858 mutex_init(&state->a6_force_wake_mutex);
4859
4860 // zero-init wait flags
4861 bitmap_zero(state->flags, SIZE_FLAGS);
4862
4863 // a6 external wake enabled?
4864 if (wake_ops) {
4865 set_bit(CAP_PERIODIC_WAKE, state->flags);
4866 }
4867
4868 state->ka6d_workqueue = create_workqueue("ka6d");
4869 if (!state->ka6d_workqueue) {
4870 printk(KERN_ERR "%s: Failed to create ka6d workqueue.\n", A6_DRIVER);
4871 goto err3;
4872 }
4873
4874 // separate wq for handling force wake timer expiry...
4875 state->ka6d_fw_workqueue = create_workqueue("ka6d_fwd");
4876 if (!state->ka6d_fw_workqueue) {
4877 printk(KERN_ERR "%s: Failed to create ka6d_fwd workqueue.\n", A6_DRIVER);
4878 goto err4;
4879 }
4880
4881 init_waitqueue_head(&state->dev_busyq);
4882
4883 INIT_WORK(&state->a6_irq_work, a6_irq_work_handler);
4884 if (test_bit(CAP_PERIODIC_WAKE, state->flags)) {
4885 INIT_WORK(&state->a6_force_wake_work, a6_force_wake_work_handler);
4886 }
4887
4888 state->cpufreq_hold_flag = 0;
4889
4890 // set device-specific driver data
4891 i2c_set_clientdata(client, state);
4892
4893 // configure sbw_tck
4894 rc = gpio_request(plat_data->sbw_tck_gpio, "a6_sbwtck");
4895 if (rc != 0) {
4896 printk(KERN_ERR "%s: request failed for sbw_tck gpio, val: %d.\n",
4897 A6_DRIVER, plat_data->sbw_tck_gpio);
4898 goto err5;
4899 }
4900
4901 rc = gpio_direction_output(plat_data->sbw_tck_gpio, 0);
4902 if (rc != 0) {
4903 printk(KERN_ERR "%s: set direction output failed for sbw_tck gpio, val: %d.\n",
4904 A6_DRIVER, plat_data->sbw_tck_gpio);
4905 goto err6;
4906 }
4907
4908 // configure sbw_wkup (this is the app -> a6 wakeup used in the JTAG handshaking)
4909 rc = gpio_request(plat_data->sbw_wkup_gpio, "a6_sbwwkup");
4910 if (rc != 0) {
4911 printk(KERN_ERR "%s: request failed for sbw_wkup gpio, val: %d.\n",
4912 A6_DRIVER, plat_data->sbw_wkup_gpio);
4913 goto err6;
4914 }
4915
4916 rc = gpio_direction_output(plat_data->sbw_wkup_gpio, 0);
4917 if (rc != 0) {
4918 printk(KERN_ERR "%s: set direction output failed for sbw_wkup gpio, val: %d.\n",
4919 A6_DRIVER, plat_data->sbw_wkup_gpio);
4920 goto err7;
4921 }
4922
4923 // configure sbw_tdio (initially configured as output and the re-configured on use)
4924 rc = gpio_request(plat_data->sbw_tdio_gpio, "a6_sbwtdio");
4925 if (rc != 0) {
4926 printk(KERN_ERR "%s: request failed for sbw_tdio gpio, val: %d.\n",
4927 A6_DRIVER, plat_data->sbw_tdio_gpio);
4928 goto err7;
4929 }
4930
4931 rc = gpio_direction_output(plat_data->sbw_tdio_gpio, 1);
4932 if (rc != 0) {
4933 printk(KERN_ERR "%s: set direction output failed for sbw_tdio gpio, val: %d.\n",
4934 A6_DRIVER, plat_data->sbw_tdio_gpio);
4935 goto err8;
4936 }
4937
4938 // configure pwr interrupt (a6 -> app)...
4939 rc = gpio_request(plat_data->pwr_gpio, "a6_pwr");
4940 if (rc != 0) {
4941 printk(KERN_ERR "%s: request failed for pwr gpio, val: %d., err: %d\n",
4942 A6_DRIVER, plat_data->pwr_gpio, rc);
4943 goto err8;
4944 }
4945
4946 rc = request_irq(gpio_to_irq(plat_data->pwr_gpio), a6_irq,
4947 IRQF_TRIGGER_FALLING,
4948 "a6", state);
4949 if (rc != 0) {
4950 printk(KERN_ERR "%s: request irq failed for pwr_gpio: val: %d, err: %d\n", A6_DRIVER,
4951 plat_data->pwr_gpio, rc);
4952 goto err9;
4953 }
4954
4955#if 0
4956 /* register as misc device */
4957 memcpy(&state->fops, &a6_fops, sizeof(struct file_operations));
4958 state->mdev.minor = MISC_DYNAMIC_MINOR;
4959 state->mdev.name = plat_data->dev_name;
4960 state->mdev.fops = &state->fops;
4961 rc = misc_register(&state->mdev);
4962 if (rc < 0) {
4963 printk(KERN_ERR "%s: Failed to register as misc device\n", A6_DRIVER);
4964 goto err10;
4965 }
4966
4967 memcpy(&state->pmem_fops, &a6_pmem_fops, sizeof(struct file_operations));
4968 state->pmem_mdev.minor = MISC_DYNAMIC_MINOR;
4969 snprintf(state->pmem_dev_name, sizeof(state->pmem_dev_name),
4970 "%s_diag", plat_data->dev_name);
4971 state->pmem_mdev.name = state->pmem_dev_name;
4972 state->pmem_mdev.fops = &state->pmem_fops;
4973 rc = misc_register(&state->pmem_mdev);
4974 if (rc < 0) {
4975 printk(KERN_ERR "%s: Failed to register as a6 pmem misc device\n", A6_DRIVER);
4976 goto err11;
4977 }
4978
4979 rc = a6_create_dev_files(state, &client->dev);
4980 if (rc < 0) {
4981 goto err12;
4982 }
4983#endif
4984
4985#ifdef A6_PQ
4986 rc = a6_start_ai_dispatch_task(state);
4987 if (rc < 0) {
4988 goto err13;
4989 }
4990#endif // A6_PQ
4991
4992 // ignore errors during initialization: these may be symptomatic of missing/corrupt
4993 // a6 fw which will need to be remedied via the A6_IOCTL_SET_FW_DATA ioctl to
4994 // re-flash fw. so its important the driver initializes successfully to handle
4995 // the request.
4996 rc = a6_init_state(client);
4997 if (rc < 0) {
4998 printk(KERN_ERR "%s: failed to initialize, err: %d\n", A6_DRIVER, rc);
4999 rc = 0;
5000 }
5001
5002 // not needed: pending work items will "flow through" if no status changes
5003 // are detected...
5004 //flush_workqueue(ka6d_workqueue);
5005
5006#ifdef A6_PQ
5007#ifdef A6_DEBUG
5008 rc = a6_create_debug_interface(state);
5009 if (rc < 0) {
5010 printk(KERN_ERR "%s: Failed to create A6 debug interface.\n", A6_DRIVER);
5011 rc = 0;
5012 }
5013#endif
5014#endif
5015
5016 if (plat_data->power_supply_connected == 1){
5017 if ( (rc = a6_fish_battery_probe (state)) < 0) {
5018 printk(KERN_ERR "%s: Failed to register power supplies, rc: %d.\n",
5019 A6_DRIVER, rc);
5020 rc = 0;
5021 }
5022
5023 batt_state = state;
5024
5025 if ((rc = a6_dock_probe(state)) < 0) {
5026 printk(KERN_ERR "%s: Failed to register dock device, rc: %d.\n",
5027 A6_DRIVER, rc);
5028 rc = 0;
5029 }
5030 }
5031
5032 printk(KERN_NOTICE "A6 driver initialized successfully!\n");
5033 return 0;
5034
5035err13:
5036#if 0
5037 a6_remove_dev_files(state, &client->dev);
5038err12:
5039 misc_register(&state->pmem_mdev);
5040err11:
5041 misc_unregister(&state->mdev);
5042err10:
5043#endif
5044 free_irq(gpio_to_irq(plat_data->pwr_gpio), state);
5045err9:
5046 gpio_free(plat_data->pwr_gpio);
5047err8:
5048 gpio_free(plat_data->sbw_tdio_gpio);
5049err7:
5050 gpio_free(plat_data->sbw_wkup_gpio);
5051err6:
5052 gpio_free(plat_data->sbw_tck_gpio);
5053err5:
5054 destroy_workqueue(state->ka6d_fw_workqueue);
5055err4:
5056 destroy_workqueue(state->ka6d_workqueue);
5057err3:
5058 kfree(state->a2a_wr_buf);
5059err1:
5060 kfree(state->a2a_rd_buf);
5061err0:
5062 kfree(state);
5063
5064 return rc;
5065}
5066
5067/******************************************************************************
5068* a6_i2c_remove()
5069******************************************************************************/
5070static int a6_i2c_remove(struct i2c_client *client)
5071{
5072 struct a6_device_state* state = (struct a6_device_state*)i2c_get_clientdata(client);
5073
5074 if (state->plat_data->power_supply_connected == 1){
5075 a6_fish_battery_remove (state);
5076 }
5077 if (state->dock_switch) {
5078 a6_dock_remove(state);
5079 }
5080
5081#if 0
5082 a6_remove_dev_files(state, &client->dev);
5083#endif
5084
5085 if (state->ka6d_workqueue) {
5086 destroy_workqueue(state->ka6d_workqueue);
5087 }
5088
5089 if (state->ka6d_fw_workqueue) {
5090 destroy_workqueue(state->ka6d_fw_workqueue);
5091 }
5092
5093 if (state->a2a_rd_buf) {
5094 kfree(state->a2a_rd_buf);
5095 }
5096
5097 if (state->a2a_wr_buf) {
5098 kfree(state->a2a_wr_buf);
5099 }
5100
5101 return 0;
5102}
5103
5104#ifdef CONFIG_PM
5105/******************************************************************************
5106* a6_i2c_suspend
5107******************************************************************************/
5108static int a6_i2c_suspend(struct i2c_client *dev, pm_message_t event)
5109{
5110 struct a6_device_state* state = (struct a6_device_state*)i2c_get_clientdata(dev);
5111
5112 set_bit(IS_SUSPENDED, state->flags);
5113 // configure a6 irq as wake-source to handle wake on a6 notifications
5114 // (charge source detection, various threshold transgressions and emergency
5115 // reset detection)...
5116 if (state->plat_data->pwr_gpio_wakeup_cap) {
5117 enable_irq_wake(gpio_to_irq(state->plat_data->pwr_gpio));
5118 }
5119
5120 a6_fish_battery_suspend (state);
5121
5122 return 0;
5123}
5124
5125/******************************************************************************
5126* a6_i2c_resume
5127******************************************************************************/
5128static int a6_i2c_resume (struct i2c_client *dev)
5129{
5130 struct a6_device_state* state = (struct a6_device_state*)i2c_get_clientdata(dev);
5131
5132 // un-configure a6 irq as wake-source...
5133 if (state->plat_data->pwr_gpio_wakeup_cap) {
5134 disable_irq_wake(gpio_to_irq(state->plat_data->pwr_gpio));
5135 }
5136
5137 clear_bit(IS_SUSPENDED, state->flags);
5138 if (test_and_clear_bit(INT_PENDING, state->flags)) {
5139 queue_work(state->ka6d_workqueue, &state->a6_irq_work);
5140 }
5141
5142 a6_fish_battery_resume (state);
5143
5144 return 0;
5145}
5146#else
5147#define a6_i2c_suspend NULL
5148#define a6_i2c_resume NULL
5149#endif /* CONFIG_PM */
5150
5151static const struct i2c_device_id a6_ids[] = {
5152 {A6_DEVICE_0, },
5153 {A6_DEVICE_1, },
5154 {},
5155};
5156
5157MODULE_DEVICE_TABLE(i2c, a6_ids);
5158
5159
5160static struct i2c_driver a6_i2c_driver = {
5161 .driver = {
5162 .name = A6_DRIVER,
5163 .owner = THIS_MODULE,
5164 },
5165 .id_table = a6_ids,
5166 .probe = a6_i2c_probe,
5167 .remove = __devexit_p(a6_i2c_remove),
5168 .suspend = a6_i2c_suspend,
5169 .resume = a6_i2c_resume,
5170};
5171
5172/*********************************************************************************
5173* a6_module_init(void)
5174***********************************************************************************/
5175static int __init a6_module_init(void)
5176{
5177 printk(KERN_INFO "Before a6 call to i2c_add_driver.\n");
5178 return i2c_add_driver(&a6_i2c_driver);
5179}
5180
5181/*********************************************************************************
5182* cy8c24894_module_exit(void)
5183***********************************************************************************/
5184static void __exit a6_module_exit(void)
5185{
5186 i2c_del_driver(&a6_i2c_driver);
5187}
5188
5189module_init(a6_module_init);
5190module_exit(a6_module_exit);
5191
5192MODULE_DESCRIPTION("A6 driver");
5193MODULE_LICENSE("GPL");