123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- #ifndef __MSM_ADC_H
- #define __MSM_ADC_H
- #include <linux/sched.h>
- #define MSM_ADC_MAX_CHAN_STR 64
- /* must be <= to the max buffer size in the modem implementation */
- #define MSM_ADC_DEV_MAX_INFLIGHT 9
- #define MSM_ADC_IOCTL_CODE 0x90
- struct msm_adc_conversion {
- /* hwmon channel number - this is not equivalent to the DAL chan */
- uint32_t chan;
- /* returned result in ms */
- int result;
- };
- struct adc_chan_result {
- /* The channel number of the requesting/requested conversion */
- uint32_t chan;
- /* The pre-calibrated digital output of a given ADC relative to the
- ADC reference */
- int32_t adc_code;
- /* in units specific for a given ADC; most ADC uses reference voltage
- * but some ADC uses reference current. This measurement here is
- * a number relative to a reference of a given ADC */
- int64_t measurement;
- /* The data meaningful for each individual channel whether it is
- * voltage, current, temperature, etc. */
- int64_t physical;
- };
- /*
- * Issue a blocking adc conversion request. Once the call returns, the data
- * can be found in the 'physical' field of adc_chan_result. This call will
- * return ENODATA if there is an invalid result returned by the modem driver.
- */
- #define MSM_ADC_REQUEST _IOWR(MSM_ADC_IOCTL_CODE, 1, \
- struct adc_chan_result)
- /*
- * Issue a non-blocking adc conversion request. The results from this
- * request can be obtained by calling AIO_READ once the transfer is
- * completed. To verify completion, the blocking call AIO_POLL can be used.
- * If there are no slot resources, this call will return an error with errno
- * set to EWOULDBLOCK.
- */
- #define MSM_ADC_AIO_REQUEST _IOWR(MSM_ADC_IOCTL_CODE, 2, \
- struct adc_chan_result)
- /*
- * Same non-blocking semantics as AIO_REQUEST, except this call will block
- * if there are no available slot resources. This call can fail with errno
- * set to EDEADLK if there are no resources and the file descriptor in question
- * has outstanding conversion requests already. This is done so the client
- * does not block on resources that can only be freed by reading the results --
- * effectively deadlocking the system. In this case, the client must read
- * pending results before proceeding to free up resources.
- */
- #define MSM_ADC_AIO_REQUEST_BLOCK_RES _IOWR(MSM_ADC_IOCTL_CODE, 3, \
- struct adc_chan_result)
- /*
- * Returns the number of pending results that are associated with a particular
- * file descriptor. If there are no pending results, this call will block until
- * there is at least one. If there are no requests queued at all on this file
- * descriptor, this call will fail with EDEADLK. This is to prevent deadlock in
- * a single-threaded scenario where POLL would never return.
- */
- #define MSM_ADC_AIO_POLL _IOR(MSM_ADC_IOCTL_CODE, 4, \
- uint32_t)
- #define MSM_ADC_FLUID_INIT _IOR(MSM_ADC_IOCTL_CODE, 5, \
- uint32_t)
- #define MSM_ADC_FLUID_DEINIT _IOR(MSM_ADC_IOCTL_CODE, 6, \
- uint32_t)
- struct msm_adc_aio_result {
- uint32_t chan;
- int result;
- };
- /*
- * Read the results from an AIO / non-blocking conversion request. AIO_POLL
- * should be used before using this command to verify how many pending requests
- * are available for the file descriptor. This call will fail with errno set to
- * ENOMSG if there are no pending messages to be read at the time of the call.
- * The call will return ENODATA if there is an invalid result returned by the
- * modem driver.
- */
- #define MSM_ADC_AIO_READ _IOR(MSM_ADC_IOCTL_CODE, 5, \
- struct adc_chan_result)
- struct msm_adc_lookup {
- /* channel name (input) */
- char name[MSM_ADC_MAX_CHAN_STR];
- /* local channel index (output) */
- uint32_t chan_idx;
- };
- /*
- * Look up a channel name and get back an index that can be used
- * as a parameter to the conversion request commands.
- */
- #define MSM_ADC_LOOKUP _IOWR(MSM_ADC_IOCTL_CODE, 6, \
- struct msm_adc_lookup)
- #ifdef __KERNEL__
- #define MSM_ADC_MAX_NUM_DEVS 3
- enum {
- ADC_CONFIG_TYPE1,
- ADC_CONFIG_TYPE2,
- ADC_CONFIG_NONE = 0xffffffff
- };
- enum {
- ADC_CALIB_CONFIG_TYPE1,
- ADC_CALIB_CONFIG_TYPE2,
- ADC_CALIB_CONFIG_TYPE3,
- ADC_CALIB_CONFIG_TYPE4,
- ADC_CALIB_CONFIG_TYPE5,
- ADC_CALIB_CONFIG_TYPE6,
- ADC_CALIB_CONFIG_TYPE7,
- ADC_CALIB_CONFIG_NONE = 0xffffffff
- };
- enum {
- /* CHAN_PATH_TYPEn is specific for each ADC driver
- and can be used however way it wants*/
- CHAN_PATH_TYPE1,
- CHAN_PATH_TYPE2,
- CHAN_PATH_TYPE3,
- CHAN_PATH_TYPE4,
- CHAN_PATH_TYPE5,
- CHAN_PATH_TYPE6,
- CHAN_PATH_TYPE7,
- CHAN_PATH_TYPE8,
- CHAN_PATH_TYPE9,
- CHAN_PATH_TYPE10,
- CHAN_PATH_TYPE11,
- CHAN_PATH_TYPE12,
- CHAN_PATH_TYPE13,
- CHAN_PATH_TYPE14,
- CHAN_PATH_TYPE15,
- CHAN_PATH_TYPE16,
- /* A given channel connects directly to the ADC */
- CHAN_PATH_TYPE_NONE = 0xffffffff
- };
- #define CHANNEL_ADC_BATT_ID 0
- #define CHANNEL_ADC_BATT_THERM 1
- #define CHANNEL_ADC_BATT_AMON 2
- #define CHANNEL_ADC_VBATT 3
- #define CHANNEL_ADC_VCOIN 4
- #define CHANNEL_ADC_VCHG 5
- #define CHANNEL_ADC_CHG_MONITOR 6
- #define CHANNEL_ADC_VPH_PWR 7
- #define CHANNEL_ADC_USB_VBUS 8
- #define CHANNEL_ADC_DIE_TEMP 9
- #define CHANNEL_ADC_DIE_TEMP_4K 0xa
- #define CHANNEL_ADC_XOTHERM 0xb
- #define CHANNEL_ADC_XOTHERM_4K 0xc
- #define CHANNEL_ADC_HDSET 0xd
- #define CHANNEL_ADC_MSM_THERM 0xe
- #define CHANNEL_ADC_625_REF 0xf
- #define CHANNEL_ADC_1250_REF 0x10
- #define CHANNEL_ADC_325_REF 0x11
- #define CHANNEL_ADC_FSM_THERM 0x12
- #define CHANNEL_ADC_PA_THERM 0x13
- enum {
- CALIB_STARTED,
- CALIB_NOT_REQUIRED = 0xffffffff,
- };
- struct linear_graph {
- int32_t offset;
- int32_t dy; /* Slope numerator */
- int32_t dx; /* Slope denominator */
- };
- struct adc_map_pt {
- int32_t x;
- int32_t y;
- };
- struct adc_properties {
- uint32_t adc_reference; /* milli-voltage for this adc */
- uint32_t bitresolution;
- bool bipolar;
- uint32_t conversiontime;
- };
- struct chan_properties {
- uint32_t gain_numerator;
- uint32_t gain_denominator;
- struct linear_graph *adc_graph;
- /* this maybe the same as adc_properties.ConversionTime
- if channel does not change the adc properties */
- uint32_t chan_conv_time;
- };
- struct msm_adc_channels {
- char *name;
- uint32_t channel_name;
- uint32_t adc_dev_instance;
- struct adc_access_fn *adc_access_fn;
- uint32_t chan_path_type;
- uint32_t adc_config_type;
- uint32_t adc_calib_type;
- int32_t (*chan_processor)(int32_t, const struct adc_properties *,
- const struct chan_properties *, struct adc_chan_result *);
- };
- struct msm_adc_platform_data {
- struct msm_adc_channels *channel;
- uint32_t num_chan_supported;
- uint32_t num_adc;
- uint32_t chan_per_adc;
- char **dev_names;
- uint32_t target_hw;
- uint32_t gpio_config;
- u32 (*adc_gpio_enable) (int);
- u32 (*adc_gpio_disable) (int);
- u32 (*adc_fluid_enable) (void);
- u32 (*adc_fluid_disable) (void);
- };
- enum hw_type {
- MSM_7x30,
- MSM_8x60,
- FSM_9xxx,
- MSM_8x25,
- };
- enum epm_gpio_config {
- MPROC_CONFIG,
- APROC_CONFIG
- };
- enum adc_request {
- START_OF_CONV,
- END_OF_CONV,
- START_OF_CALIBRATION,
- END_OF_CALIBRATION,
- };
- struct adc_dev_spec {
- uint32_t hwmon_dev_idx;
- struct dal_dev_spec {
- uint32_t dev_idx;
- uint32_t chan_idx;
- } dal;
- };
- struct dal_conv_request {
- struct dal_dev_spec target;
- void *cb_h;
- };
- struct dal_adc_result {
- uint32_t status;
- uint32_t token;
- uint32_t dev_idx;
- uint32_t chan_idx;
- int physical;
- uint32_t percent;
- uint32_t microvolts;
- uint32_t reserved;
- };
- struct dal_conv_slot {
- void *cb_h;
- struct dal_adc_result result;
- struct completion comp;
- struct list_head list;
- uint32_t idx;
- uint32_t chan_idx;
- bool blocking;
- struct msm_client_data *client;
- };
- struct dal_translation {
- uint32_t dal_dev_idx;
- uint32_t hwmon_dev_idx;
- uint32_t hwmon_start;
- uint32_t hwmon_end;
- };
- struct msm_client_data {
- struct list_head complete_list;
- bool online;
- int32_t adc_chan;
- uint32_t num_complete;
- uint32_t num_outstanding;
- wait_queue_head_t data_wait;
- wait_queue_head_t outst_wait;
- struct mutex lock;
- };
- struct adc_conv_slot {
- void *cb_h;
- union {
- struct adc_chan_result result;
- struct dal_adc_result dal_result;
- } conv;
- struct completion comp;
- struct completion *compk;
- struct list_head list;
- uint32_t idx;
- enum adc_request adc_request;
- bool blocking;
- struct msm_client_data *client;
- struct work_struct work;
- struct chan_properties chan_properties;
- uint32_t chan_path;
- uint32_t chan_adc_config;
- uint32_t chan_adc_calib;
- };
- struct adc_access_fn {
- int32_t (*adc_select_chan_and_start_conv)(uint32_t,
- struct adc_conv_slot*);
- int32_t (*adc_read_adc_code)(uint32_t dev_instance, int32_t *data);
- struct adc_properties *(*adc_get_properties)(uint32_t dev_instance);
- void (*adc_slot_request)(uint32_t dev_instance,
- struct adc_conv_slot **);
- void (*adc_restore_slot)(uint32_t dev_instance,
- struct adc_conv_slot *slot);
- int32_t (*adc_calibrate)(uint32_t dev_instance, struct adc_conv_slot*,
- int *);
- };
- void msm_adc_wq_work(struct work_struct *work);
- void msm_adc_conv_cb(void *context, u32 param, void *evt_buf, u32 len);
- #ifdef CONFIG_SENSORS_MSM_ADC
- int32_t adc_channel_open(uint32_t channel, void **h);
- int32_t adc_channel_close(void *h);
- int32_t adc_channel_request_conv(void *h, struct completion *conv_complete_evt);
- int32_t adc_channel_read_result(void *h, struct adc_chan_result *chan_result);
- #else
- static inline int32_t adc_channel_open(uint32_t channel, void **h)
- {
- pr_err("%s.not supported.\n", __func__);
- return -ENODEV;
- }
- static inline int32_t adc_channel_close(void *h)
- {
- pr_err("%s.not supported.\n", __func__);
- return -ENODEV;
- }
- static inline int32_t
- adc_channel_request_conv(void *h, struct completion *conv_complete_evt)
- {
- pr_err("%s.not supported.\n", __func__);
- return -ENODEV;
- }
- static inline int32_t
- adc_channel_read_result(void *h, struct adc_chan_result *chan_result)
- {
- pr_err("%s.not supported.\n", __func__);
- return -ENODEV;
- }
- #endif /* CONFIG_SENSORS_MSM_ADC */
- #endif
- #endif /* __MSM_ADC_H */
|