blob: b8ab5990cee6dc569598213ef90033d1284ca2c1 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001#ifndef __MSM_ADC_H
2#define __MSM_ADC_H
3
4#include <linux/sched.h>
5
6#define MSM_ADC_MAX_CHAN_STR 64
7
8/* must be <= to the max buffer size in the modem implementation */
9#define MSM_ADC_DEV_MAX_INFLIGHT 9
10
11#define MSM_ADC_IOCTL_CODE 0x90
12
13struct msm_adc_conversion {
14 /* hwmon channel number - this is not equivalent to the DAL chan */
15 uint32_t chan;
16 /* returned result in ms */
17 int result;
18};
19
20struct adc_chan_result {
21 /* The channel number of the requesting/requested conversion */
22 uint32_t chan;
23 /* The pre-calibrated digital output of a given ADC relative to the
24 ADC reference */
25 int32_t adc_code;
26 /* in units specific for a given ADC; most ADC uses reference voltage
27 * but some ADC uses reference current. This measurement here is
28 * a number relative to a reference of a given ADC */
29 int64_t measurement;
30 /* The data meaningful for each individual channel whether it is
31 * voltage, current, temperature, etc. */
32 int64_t physical;
33};
34
35/*
36 * Issue a blocking adc conversion request. Once the call returns, the data
37 * can be found in the 'physical' field of adc_chan_result. This call will
38 * return ENODATA if there is an invalid result returned by the modem driver.
39 */
40#define MSM_ADC_REQUEST _IOWR(MSM_ADC_IOCTL_CODE, 1, \
41 struct adc_chan_result)
42
43/*
44 * Issue a non-blocking adc conversion request. The results from this
45 * request can be obtained by calling AIO_READ once the transfer is
46 * completed. To verify completion, the blocking call AIO_POLL can be used.
47 * If there are no slot resources, this call will return an error with errno
48 * set to EWOULDBLOCK.
49 */
50#define MSM_ADC_AIO_REQUEST _IOWR(MSM_ADC_IOCTL_CODE, 2, \
51 struct adc_chan_result)
52
53/*
54 * Same non-blocking semantics as AIO_REQUEST, except this call will block
55 * if there are no available slot resources. This call can fail with errno
56 * set to EDEADLK if there are no resources and the file descriptor in question
57 * has outstanding conversion requests already. This is done so the client
58 * does not block on resources that can only be freed by reading the results --
59 * effectively deadlocking the system. In this case, the client must read
60 * pending results before proceeding to free up resources.
61 */
62#define MSM_ADC_AIO_REQUEST_BLOCK_RES _IOWR(MSM_ADC_IOCTL_CODE, 3, \
63 struct adc_chan_result)
64
65/*
66 * Returns the number of pending results that are associated with a particular
67 * file descriptor. If there are no pending results, this call will block until
68 * there is at least one. If there are no requests queued at all on this file
69 * descriptor, this call will fail with EDEADLK. This is to prevent deadlock in
70 * a single-threaded scenario where POLL would never return.
71 */
72#define MSM_ADC_AIO_POLL _IOR(MSM_ADC_IOCTL_CODE, 4, \
73 uint32_t)
74
75#define MSM_ADC_FLUID_INIT _IOR(MSM_ADC_IOCTL_CODE, 5, \
76 uint32_t)
77
78#define MSM_ADC_FLUID_DEINIT _IOR(MSM_ADC_IOCTL_CODE, 6, \
79 uint32_t)
80
81struct msm_adc_aio_result {
82 uint32_t chan;
83 int result;
84};
85
86/*
87 * Read the results from an AIO / non-blocking conversion request. AIO_POLL
88 * should be used before using this command to verify how many pending requests
89 * are available for the file descriptor. This call will fail with errno set to
90 * ENOMSG if there are no pending messages to be read at the time of the call.
91 * The call will return ENODATA if there is an invalid result returned by the
92 * modem driver.
93 */
94#define MSM_ADC_AIO_READ _IOR(MSM_ADC_IOCTL_CODE, 5, \
95 struct adc_chan_result)
96
97struct msm_adc_lookup {
98 /* channel name (input) */
99 char name[MSM_ADC_MAX_CHAN_STR];
100 /* local channel index (output) */
101 uint32_t chan_idx;
102};
103
104/*
105 * Look up a channel name and get back an index that can be used
106 * as a parameter to the conversion request commands.
107 */
108#define MSM_ADC_LOOKUP _IOWR(MSM_ADC_IOCTL_CODE, 6, \
109 struct msm_adc_lookup)
110
111
112#ifdef __KERNEL__
113#define MSM_ADC_MAX_NUM_DEVS 3
114
115enum {
116 ADC_CONFIG_TYPE1,
117 ADC_CONFIG_TYPE2,
118 ADC_CONFIG_NONE = 0xffffffff
119};
120
121enum {
122 ADC_CALIB_CONFIG_TYPE1,
123 ADC_CALIB_CONFIG_TYPE2,
124 ADC_CALIB_CONFIG_TYPE3,
125 ADC_CALIB_CONFIG_TYPE4,
126 ADC_CALIB_CONFIG_TYPE5,
127 ADC_CALIB_CONFIG_TYPE6,
128 ADC_CALIB_CONFIG_TYPE7,
129 ADC_CALIB_CONFIG_NONE = 0xffffffff
130};
131
132enum {
133 /* CHAN_PATH_TYPEn is specific for each ADC driver
134 and can be used however way it wants*/
135 CHAN_PATH_TYPE1,
136 CHAN_PATH_TYPE2,
137 CHAN_PATH_TYPE3,
138 CHAN_PATH_TYPE4,
139 CHAN_PATH_TYPE5,
140 CHAN_PATH_TYPE6,
141 CHAN_PATH_TYPE7,
142 CHAN_PATH_TYPE8,
143 CHAN_PATH_TYPE9,
144 CHAN_PATH_TYPE10,
145 CHAN_PATH_TYPE11,
146 CHAN_PATH_TYPE12,
147 CHAN_PATH_TYPE13,
148 CHAN_PATH_TYPE14,
149 CHAN_PATH_TYPE15,
150 CHAN_PATH_TYPE16,
151 /* A given channel connects directly to the ADC */
152 CHAN_PATH_TYPE_NONE = 0xffffffff
153};
154
155#define CHANNEL_ADC_BATT_ID 0
156#define CHANNEL_ADC_BATT_THERM 1
157#define CHANNEL_ADC_BATT_AMON 2
158#define CHANNEL_ADC_VBATT 3
159#define CHANNEL_ADC_VCOIN 4
160#define CHANNEL_ADC_VCHG 5
161#define CHANNEL_ADC_CHG_MONITOR 6
162#define CHANNEL_ADC_VPH_PWR 7
163#define CHANNEL_ADC_USB_VBUS 8
164#define CHANNEL_ADC_DIE_TEMP 9
165#define CHANNEL_ADC_DIE_TEMP_4K 0xa
166#define CHANNEL_ADC_XOTHERM 0xb
167#define CHANNEL_ADC_XOTHERM_4K 0xc
168#define CHANNEL_ADC_HDSET 0xd
169#define CHANNEL_ADC_MSM_THERM 0xe
170#define CHANNEL_ADC_625_REF 0xf
171#define CHANNEL_ADC_1250_REF 0x10
172#define CHANNEL_ADC_325_REF 0x11
173#define CHANNEL_ADC_FSM_THERM 0x12
174#define CHANNEL_ADC_PA_THERM 0x13
175
176enum {
177 CALIB_STARTED,
178 CALIB_NOT_REQUIRED = 0xffffffff,
179};
180
181struct linear_graph {
182 int32_t offset;
183 int32_t dy; /* Slope numerator */
184 int32_t dx; /* Slope denominator */
185};
186
187struct adc_map_pt {
188 int32_t x;
189 int32_t y;
190};
191
192struct adc_properties {
193 uint32_t adc_reference; /* milli-voltage for this adc */
194 uint32_t bitresolution;
195 bool bipolar;
196 uint32_t conversiontime;
197};
198
199struct chan_properties {
200 uint32_t gain_numerator;
201 uint32_t gain_denominator;
202 struct linear_graph *adc_graph;
203/* this maybe the same as adc_properties.ConversionTime
204 if channel does not change the adc properties */
205 uint32_t chan_conv_time;
206};
207
208struct msm_adc_channels {
209 char *name;
210 uint32_t channel_name;
211 uint32_t adc_dev_instance;
212 struct adc_access_fn *adc_access_fn;
213 uint32_t chan_path_type;
214 uint32_t adc_config_type;
215 uint32_t adc_calib_type;
216 int32_t (*chan_processor)(int32_t, const struct adc_properties *,
217 const struct chan_properties *, struct adc_chan_result *);
218
219};
220
221struct msm_adc_platform_data {
222 struct msm_adc_channels *channel;
223 uint32_t num_chan_supported;
224 uint32_t num_adc;
225 uint32_t chan_per_adc;
226 char **dev_names;
227 uint32_t target_hw;
228 uint32_t gpio_config;
229 u32 (*adc_gpio_enable) (int);
230 u32 (*adc_gpio_disable) (int);
231 u32 (*adc_fluid_enable) (void);
232 u32 (*adc_fluid_disable) (void);
233};
234
235enum hw_type {
236 MSM_7x30,
237 MSM_8x60,
238 FSM_9xxx,
239};
240
241enum epm_gpio_config {
242 MPROC_CONFIG,
243 APROC_CONFIG
244};
245
246enum adc_request {
247 START_OF_CONV,
248 END_OF_CONV,
249 START_OF_CALIBRATION,
250 END_OF_CALIBRATION,
251};
252
253struct adc_dev_spec {
254 uint32_t hwmon_dev_idx;
255 struct dal_dev_spec {
256 uint32_t dev_idx;
257 uint32_t chan_idx;
258 } dal;
259};
260
261struct dal_conv_request {
262 struct dal_dev_spec target;
263 void *cb_h;
264};
265
266struct dal_adc_result {
267 uint32_t status;
268 uint32_t token;
269 uint32_t dev_idx;
270 uint32_t chan_idx;
271 int physical;
272 uint32_t percent;
273 uint32_t microvolts;
274 uint32_t reserved;
275};
276
277struct dal_conv_slot {
278 void *cb_h;
279 struct dal_adc_result result;
280 struct completion comp;
281 struct list_head list;
282 uint32_t idx;
283 uint32_t chan_idx;
284 bool blocking;
285 struct msm_client_data *client;
286};
287
288struct dal_translation {
289 uint32_t dal_dev_idx;
290 uint32_t hwmon_dev_idx;
291 uint32_t hwmon_start;
292 uint32_t hwmon_end;
293};
294
295struct msm_client_data {
296 struct list_head complete_list;
297 bool online;
298 int32_t adc_chan;
299 uint32_t num_complete;
300 uint32_t num_outstanding;
301 wait_queue_head_t data_wait;
302 wait_queue_head_t outst_wait;
303 struct mutex lock;
304};
305
306struct adc_conv_slot {
307 void *cb_h;
308 union {
309 struct adc_chan_result result;
310 struct dal_adc_result dal_result;
311 } conv;
312 struct completion comp;
313 struct completion *compk;
314 struct list_head list;
315 uint32_t idx;
316 enum adc_request adc_request;
317 bool blocking;
318 struct msm_client_data *client;
319 struct work_struct work;
320 struct chan_properties chan_properties;
321 uint32_t chan_path;
322 uint32_t chan_adc_config;
323 uint32_t chan_adc_calib;
324};
325
326struct adc_access_fn {
327 int32_t (*adc_select_chan_and_start_conv)(uint32_t,
328 struct adc_conv_slot*);
329 int32_t (*adc_read_adc_code)(uint32_t dev_instance, int32_t *data);
330 struct adc_properties *(*adc_get_properties)(uint32_t dev_instance);
331 void (*adc_slot_request)(uint32_t dev_instance,
332 struct adc_conv_slot **);
333 void (*adc_restore_slot)(uint32_t dev_instance,
334 struct adc_conv_slot *slot);
335 int32_t (*adc_calibrate)(uint32_t dev_instance, struct adc_conv_slot*,
336 int *);
337};
338
339void msm_adc_wq_work(struct work_struct *work);
340void msm_adc_conv_cb(void *context, u32 param, void *evt_buf, u32 len);
341int32_t adc_channel_open(uint32_t channel, void **h);
342int32_t adc_channel_close(void *h);
343int32_t adc_channel_request_conv(void *h, struct completion *conv_complete_evt);
344int32_t adc_channel_read_result(void *h, struct adc_chan_result *chan_result);
345int32_t adc_calib_request(void *h, struct completion *calib_complete_evt);
346#endif
347#endif /* __MSM_ADC_H */