^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * TWL4030 MADC module driver-This driver monitors the real time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * conversion of analog signals like battery temperature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * battery type, battery level etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * J Keerthy <j-keerthy@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Based on twl4030-madc.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Copyright (C) 2008 Nokia Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Mikko Ylinen <mikko.k.ylinen@nokia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Amit Kucheria <amit.kucheria@canonical.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/mfd/twl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define TWL4030_MADC_MAX_CHANNELS 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define TWL4030_MADC_CTRL1 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define TWL4030_MADC_CTRL2 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define TWL4030_MADC_RTSELECT_LSB 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define TWL4030_MADC_SW1SELECT_LSB 0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define TWL4030_MADC_SW2SELECT_LSB 0x0A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define TWL4030_MADC_RTAVERAGE_LSB 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define TWL4030_MADC_SW1AVERAGE_LSB 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define TWL4030_MADC_SW2AVERAGE_LSB 0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define TWL4030_MADC_CTRL_SW1 0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define TWL4030_MADC_CTRL_SW2 0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define TWL4030_MADC_RTCH0_LSB 0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define TWL4030_MADC_GPCH0_LSB 0x37
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define TWL4030_MADC_MADCON (1 << 0) /* MADC power on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define TWL4030_MADC_BUSY (1 << 0) /* MADC busy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* MADC conversion completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define TWL4030_MADC_EOC_SW (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* MADC SWx start conversion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define TWL4030_MADC_SW_START (1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define TWL4030_MADC_ADCIN0 (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define TWL4030_MADC_ADCIN1 (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define TWL4030_MADC_ADCIN2 (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define TWL4030_MADC_ADCIN3 (1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define TWL4030_MADC_ADCIN4 (1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define TWL4030_MADC_ADCIN5 (1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define TWL4030_MADC_ADCIN6 (1 << 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define TWL4030_MADC_ADCIN7 (1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define TWL4030_MADC_ADCIN8 (1 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define TWL4030_MADC_ADCIN9 (1 << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define TWL4030_MADC_ADCIN10 (1 << 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define TWL4030_MADC_ADCIN11 (1 << 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define TWL4030_MADC_ADCIN12 (1 << 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define TWL4030_MADC_ADCIN13 (1 << 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define TWL4030_MADC_ADCIN14 (1 << 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define TWL4030_MADC_ADCIN15 (1 << 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* Fixed channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define TWL4030_MADC_BTEMP TWL4030_MADC_ADCIN1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define TWL4030_MADC_VBUS TWL4030_MADC_ADCIN8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define TWL4030_MADC_VBKB TWL4030_MADC_ADCIN9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define TWL4030_MADC_ICHG TWL4030_MADC_ADCIN10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define TWL4030_MADC_VCHG TWL4030_MADC_ADCIN11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define TWL4030_MADC_VBAT TWL4030_MADC_ADCIN12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* Step size and prescaler ratio */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define TEMP_STEP_SIZE 147
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define TEMP_PSR_R 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define CURR_STEP_SIZE 147
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define CURR_PSR_R1 44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define CURR_PSR_R2 88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define TWL4030_BCI_BCICTL1 0x23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define TWL4030_BCI_CGAIN 0x020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define TWL4030_BCI_MESBAT (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define TWL4030_BCI_TYPEN (1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define TWL4030_BCI_ITHEN (1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define REG_BCICTL2 0x024
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define TWL4030_BCI_ITHSENS 0x007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* Register and bits for GPBR1 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define TWL4030_REG_GPBR1 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define TWL4030_GPBR1_MADC_HFCLK_EN (1 << 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define TWL4030_USB_SEL_MADC_MCPC (1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define TWL4030_USB_CARKIT_ANA_CTRL 0xBB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct twl4030_madc_conversion_method {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) u8 sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u8 avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u8 rbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u8 ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * struct twl4030_madc_request - madc request packet for channel conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * @channels: 16 bit bitmap for individual channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * @do_avg: sample the input channel for 4 consecutive cycles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * @method: RT, SW1, SW2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * @type: Polling or interrupt based method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * @active: Flag if request is active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * @result_pending: Flag from irq handler, that result is ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * @raw: Return raw value, do not convert it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * @rbuf: Result buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct twl4030_madc_request {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) unsigned long channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) bool do_avg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u16 method;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u16 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) bool active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) bool result_pending;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) bool raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int rbuf[TWL4030_MADC_MAX_CHANNELS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) enum conversion_methods {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) TWL4030_MADC_RT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) TWL4030_MADC_SW1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) TWL4030_MADC_SW2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) TWL4030_MADC_NUM_METHODS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) enum sample_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) TWL4030_MADC_WAIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) TWL4030_MADC_IRQ_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) TWL4030_MADC_IRQ_REARM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * struct twl4030_madc_data - a container for madc info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * @dev: Pointer to device structure for madc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * @lock: Mutex protecting this data structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * @usb3v1: Pointer to bias regulator for madc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * @requests: Array of request struct corresponding to SW1, SW2 and RT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * @use_second_irq: IRQ selection (main or co-processor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * @imr: Interrupt mask register of MADC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * @isr: Interrupt status register of MADC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct twl4030_madc_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct regulator *usb3v1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) bool use_second_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) u8 imr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u8 isr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static int twl4030_madc_conversion(struct twl4030_madc_request *req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int twl4030_madc_read(struct iio_dev *iio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct twl4030_madc_data *madc = iio_priv(iio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct twl4030_madc_request req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) req.method = madc->use_second_irq ? TWL4030_MADC_SW2 : TWL4030_MADC_SW1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) req.channels = BIT(chan->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) req.active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) req.type = TWL4030_MADC_WAIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) req.raw = !(mask == IIO_CHAN_INFO_PROCESSED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) req.do_avg = (mask == IIO_CHAN_INFO_AVERAGE_RAW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ret = twl4030_madc_conversion(&req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) *val = req.rbuf[chan->channel];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static const struct iio_info twl4030_madc_iio_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) .read_raw = &twl4030_madc_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define TWL4030_ADC_CHANNEL(_channel, _type, _name) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .type = _type, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .channel = _channel, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) BIT(IIO_CHAN_INFO_AVERAGE_RAW) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) BIT(IIO_CHAN_INFO_PROCESSED), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .datasheet_name = _name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .indexed = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static const struct iio_chan_spec twl4030_madc_iio_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) TWL4030_ADC_CHANNEL(0, IIO_VOLTAGE, "ADCIN0"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) TWL4030_ADC_CHANNEL(1, IIO_TEMP, "ADCIN1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) TWL4030_ADC_CHANNEL(2, IIO_VOLTAGE, "ADCIN2"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) TWL4030_ADC_CHANNEL(3, IIO_VOLTAGE, "ADCIN3"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) TWL4030_ADC_CHANNEL(4, IIO_VOLTAGE, "ADCIN4"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) TWL4030_ADC_CHANNEL(5, IIO_VOLTAGE, "ADCIN5"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) TWL4030_ADC_CHANNEL(6, IIO_VOLTAGE, "ADCIN6"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) TWL4030_ADC_CHANNEL(7, IIO_VOLTAGE, "ADCIN7"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) TWL4030_ADC_CHANNEL(8, IIO_VOLTAGE, "ADCIN8"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) TWL4030_ADC_CHANNEL(9, IIO_VOLTAGE, "ADCIN9"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) TWL4030_ADC_CHANNEL(10, IIO_CURRENT, "ADCIN10"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) TWL4030_ADC_CHANNEL(11, IIO_VOLTAGE, "ADCIN11"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) TWL4030_ADC_CHANNEL(12, IIO_VOLTAGE, "ADCIN12"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) TWL4030_ADC_CHANNEL(13, IIO_VOLTAGE, "ADCIN13"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) TWL4030_ADC_CHANNEL(14, IIO_VOLTAGE, "ADCIN14"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) TWL4030_ADC_CHANNEL(15, IIO_VOLTAGE, "ADCIN15"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static struct twl4030_madc_data *twl4030_madc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct twl4030_prescale_divider_ratios {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) s16 numerator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) s16 denominator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static const struct twl4030_prescale_divider_ratios
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) twl4030_divider_ratios[16] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {1, 1}, /* CHANNEL 0 No Prescaler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {1, 1}, /* CHANNEL 1 No Prescaler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {6, 10}, /* CHANNEL 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {6, 10}, /* CHANNEL 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {6, 10}, /* CHANNEL 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {6, 10}, /* CHANNEL 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {6, 10}, /* CHANNEL 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {6, 10}, /* CHANNEL 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {3, 14}, /* CHANNEL 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {1, 3}, /* CHANNEL 9 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {1, 1}, /* CHANNEL 10 No Prescaler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {15, 100}, /* CHANNEL 11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {1, 4}, /* CHANNEL 12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {1, 1}, /* CHANNEL 13 Reserved channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {1, 1}, /* CHANNEL 14 Reseved channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {5, 11}, /* CHANNEL 15 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /* Conversion table from -3 to 55 degrees Celcius */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static int twl4030_therm_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 30800, 29500, 28300, 27100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 17900, 17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 12600, 12100, 11600, 11200, 10800, 10400, 10000, 9630, 9280,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 8950, 8620, 8310, 8020, 7730, 7460, 7200, 6950, 6710,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 6470, 6250, 6040, 5830, 5640, 5450, 5260, 5090, 4920,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 4760, 4600, 4450, 4310, 4170, 4040, 3910, 3790, 3670,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 3550
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * Structure containing the registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * of different conversion methods supported by MADC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * Hardware or RT real time conversion request initiated by external host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * processor for RT Signal conversions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * External host processors can also request for non RT conversions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * SW1 and SW2 software conversions also called asynchronous or GPC request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) [TWL4030_MADC_RT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) .sel = TWL4030_MADC_RTSELECT_LSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) .avg = TWL4030_MADC_RTAVERAGE_LSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) .rbase = TWL4030_MADC_RTCH0_LSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) [TWL4030_MADC_SW1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) .sel = TWL4030_MADC_SW1SELECT_LSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) .avg = TWL4030_MADC_SW1AVERAGE_LSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) .rbase = TWL4030_MADC_GPCH0_LSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .ctrl = TWL4030_MADC_CTRL_SW1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) [TWL4030_MADC_SW2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) .sel = TWL4030_MADC_SW2SELECT_LSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) .avg = TWL4030_MADC_SW2AVERAGE_LSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) .rbase = TWL4030_MADC_GPCH0_LSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) .ctrl = TWL4030_MADC_CTRL_SW2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * twl4030_madc_channel_raw_read() - Function to read a particular channel value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * @madc: pointer to struct twl4030_madc_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * @reg: lsb of ADC Channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * Return: 0 on success, an error code otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * For each ADC channel, we have MSB and LSB register pair. MSB address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * is always LSB address+1. reg parameter is the address of LSB register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ret = twl_i2c_read_u16(TWL4030_MODULE_MADC, &val, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) dev_err(madc->dev, "unable to read register 0x%X\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return (int)(val >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * Return battery temperature in degrees Celsius
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * Or < 0 on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static int twl4030battery_temperature(int raw_volt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int temp, curr, volt, res, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* Getting and calculating the supply current in micro amperes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) REG_BCICTL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) curr = ((val & TWL4030_BCI_ITHSENS) + 1) * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /* Getting and calculating the thermistor resistance in ohms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) res = volt * 1000 / curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* calculating temperature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) for (temp = 58; temp >= 0; temp--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) int actual = twl4030_therm_tbl[temp];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if ((actual - res) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return temp + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static int twl4030battery_current(int raw_volt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) TWL4030_BCI_BCICTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (val & TWL4030_BCI_CGAIN) /* slope of 0.44 mV/mA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) else /* slope of 0.88 mV/mA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * Function to read channel values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * @madc - pointer to twl4030_madc_data struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * @reg_base - Base address of the first channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * @Channels - 16 bit bitmap. If the bit is set, channel's value is read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * @buf - The channel values are stored here. if read fails error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * @raw - Return raw values without conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * value is stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * Returns the number of successfully read channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) u8 reg_base, unsigned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) long channels, int *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) bool raw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) reg = reg_base + (2 * i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) buf[i] = twl4030_madc_channel_raw_read(madc, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (buf[i] < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) dev_err(madc->dev, "Unable to read register 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return buf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (raw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) switch (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) buf[i] = twl4030battery_current(buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (buf[i] < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) dev_err(madc->dev, "err reading current\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return buf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) buf[i] = buf[i] - 750;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) buf[i] = twl4030battery_temperature(buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (buf[i] < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) dev_err(madc->dev, "err reading temperature\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return buf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) buf[i] -= 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /* Analog Input (V) = conv_result * step_size / R
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * conv_result = decimal value of 10-bit conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) * step size = 1.5 / (2 ^ 10 -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * R = Prescaler ratio for input channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * Result given in mV hence multiplied by 1000.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) buf[i] = (buf[i] * 3 * 1000 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) twl4030_divider_ratios[i].denominator)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) / (2 * 1023 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) twl4030_divider_ratios[i].numerator);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * Disables irq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * @madc - pointer to twl4030_madc_data struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * @id - irq number to be disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * corresponding to RT, SW1, SW2 conversion requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * Returns error if i2c read/write fails.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static int twl4030_madc_disable_irq(struct twl4030_madc_data *madc, u8 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) dev_err(madc->dev, "unable to read imr register 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) madc->imr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) val |= (1 << id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) dev_err(madc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) "unable to write imr register 0x%X\n", madc->imr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static irqreturn_t twl4030_madc_threaded_irq_handler(int irq, void *_madc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct twl4030_madc_data *madc = _madc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) const struct twl4030_madc_conversion_method *method;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) u8 isr_val, imr_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct twl4030_madc_request *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) mutex_lock(&madc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &isr_val, madc->isr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) dev_err(madc->dev, "unable to read isr register 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) madc->isr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) goto err_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &imr_val, madc->imr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) dev_err(madc->dev, "unable to read imr register 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) madc->imr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) goto err_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) isr_val &= ~imr_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (!(isr_val & (1 << i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ret = twl4030_madc_disable_irq(madc, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) dev_dbg(madc->dev, "Disable interrupt failed %d\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) madc->requests[i].result_pending = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) r = &madc->requests[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) /* No pending results for this method, move to next one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (!r->result_pending)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) method = &twl4030_conversion_methods[r->method];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* Read results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) twl4030_madc_read_channels(madc, method->rbase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) r->channels, r->rbuf, r->raw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /* Free request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) r->result_pending = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) r->active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) mutex_unlock(&madc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) err_i2c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * In case of error check whichever request is active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * and service the same.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) r = &madc->requests[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (!r->active)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) method = &twl4030_conversion_methods[r->method];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /* Read results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) twl4030_madc_read_channels(madc, method->rbase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) r->channels, r->rbuf, r->raw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* Free request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) r->result_pending = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) r->active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) mutex_unlock(&madc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * Function which enables the madc conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * by writing to the control register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * @madc - pointer to twl4030_madc_data struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * @conv_method - can be TWL4030_MADC_RT, TWL4030_MADC_SW2, TWL4030_MADC_SW1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * corresponding to RT SW1 or SW2 conversion methods.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * Returns 0 if succeeds else a negative error value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static int twl4030_madc_start_conversion(struct twl4030_madc_data *madc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) int conv_method)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) const struct twl4030_madc_conversion_method *method;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (conv_method != TWL4030_MADC_SW1 && conv_method != TWL4030_MADC_SW2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) method = &twl4030_conversion_methods[conv_method];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, TWL4030_MADC_SW_START,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) method->ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) dev_err(madc->dev, "unable to write ctrl register 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) method->ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * Function that waits for conversion to be ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * @madc - pointer to twl4030_madc_data struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * @timeout_ms - timeout value in milliseconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * @status_reg - ctrl register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * returns 0 if succeeds else a negative error value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static int twl4030_madc_wait_conversion_ready(struct twl4030_madc_data *madc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) unsigned int timeout_ms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) u8 status_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) timeout = jiffies + msecs_to_jiffies(timeout_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, ®, status_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) dev_err(madc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) "unable to read status register 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) status_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) usleep_range(500, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) } while (!time_after(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) dev_err(madc->dev, "conversion timeout!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * An exported function which can be called from other kernel drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * @req twl4030_madc_request structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * req->rbuf will be filled with read values of channels based on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * channel index. If a particular channel reading fails there will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * be a negative error value in the corresponding array element.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * returns 0 if succeeds else error value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) static int twl4030_madc_conversion(struct twl4030_madc_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) const struct twl4030_madc_conversion_method *method;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (!req || !twl4030_madc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) mutex_lock(&twl4030_madc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /* Do we have a conversion request ongoing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (twl4030_madc->requests[req->method].active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) method = &twl4030_conversion_methods[req->method];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /* Select channels to be converted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ret = twl_i2c_write_u16(TWL4030_MODULE_MADC, req->channels, method->sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) dev_err(twl4030_madc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) "unable to write sel register 0x%X\n", method->sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /* Select averaging for all channels if do_avg is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (req->do_avg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) ret = twl_i2c_write_u16(TWL4030_MODULE_MADC, req->channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) method->avg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) dev_err(twl4030_madc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) "unable to write avg register 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) method->avg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) /* With RT method we should not be here anymore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (req->method == TWL4030_MADC_RT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) twl4030_madc->requests[req->method].active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /* Wait until conversion is ready (ctrl register returns EOC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) ret = twl4030_madc_wait_conversion_ready(twl4030_madc, 5, method->ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) twl4030_madc->requests[req->method].active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) ret = twl4030_madc_read_channels(twl4030_madc, method->rbase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) req->channels, req->rbuf, req->raw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) twl4030_madc->requests[req->method].active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) mutex_unlock(&twl4030_madc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * twl4030_madc_set_current_generator() - setup bias current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * @madc: pointer to twl4030_madc_data struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * @chan: can be one of the two values:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * 0 - Enables bias current for main battery type reading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * 1 - Enables bias current for main battery temperature sensing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * @on: enable or disable chan.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * Function to enable or disable bias current for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * main battery type reading or temperature sensing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) int chan, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) int regmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) u8 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) ®val, TWL4030_BCI_BCICTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) dev_err(madc->dev, "unable to read BCICTL1 reg 0x%X",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) TWL4030_BCI_BCICTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) regmask = chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) regval |= regmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) regval &= ~regmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) regval, TWL4030_BCI_BCICTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) dev_err(madc->dev, "unable to write BCICTL1 reg 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) TWL4030_BCI_BCICTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) * Function that sets MADC software power on bit to enable MADC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * @madc - pointer to twl4030_madc_data struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * @on - Enable or disable MADC software power on bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * returns error if i2c read/write fails else 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) u8 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) ®val, TWL4030_MADC_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) dev_err(madc->dev, "unable to read madc ctrl1 reg 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) TWL4030_MADC_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) regval |= TWL4030_MADC_MADCON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) regval &= ~TWL4030_MADC_MADCON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, regval, TWL4030_MADC_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) dev_err(madc->dev, "unable to write madc ctrl1 reg 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) TWL4030_MADC_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * Initialize MADC and request for threaded irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static int twl4030_madc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct twl4030_madc_data *madc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct twl4030_madc_platform_data *pdata = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) int irq, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) u8 regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct iio_dev *iio_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (!pdata && !np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) dev_err(&pdev->dev, "neither platform data nor Device Tree node available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) iio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*madc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (!iio_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) dev_err(&pdev->dev, "failed allocating iio device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) madc = iio_priv(iio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) madc->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) iio_dev->name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) iio_dev->info = &twl4030_madc_iio_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) iio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) iio_dev->channels = twl4030_madc_iio_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) iio_dev->num_channels = ARRAY_SIZE(twl4030_madc_iio_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * Phoenix provides 2 interrupt lines. The first one is connected to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) * the OMAP. The other one can be connected to the other processor such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) * as modem. Hence two separate ISR and IMR registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) madc->use_second_irq = (pdata->irq_line != 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) madc->use_second_irq = of_property_read_bool(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) "ti,system-uses-second-madc-irq");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) madc->imr = madc->use_second_irq ? TWL4030_MADC_IMR2 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) TWL4030_MADC_IMR1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) madc->isr = madc->use_second_irq ? TWL4030_MADC_ISR2 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) TWL4030_MADC_ISR1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) ret = twl4030_madc_set_power(madc, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) ret = twl4030_madc_set_current_generator(madc, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) goto err_current_generator;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) ®val, TWL4030_BCI_BCICTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) dev_err(&pdev->dev, "unable to read reg BCI CTL1 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) TWL4030_BCI_BCICTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) goto err_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) regval |= TWL4030_BCI_MESBAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) regval, TWL4030_BCI_BCICTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) dev_err(&pdev->dev, "unable to write reg BCI Ctl1 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) TWL4030_BCI_BCICTL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) goto err_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) /* Check that MADC clock is on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, ®val, TWL4030_REG_GPBR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) dev_err(&pdev->dev, "unable to read reg GPBR1 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) TWL4030_REG_GPBR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) goto err_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) /* If MADC clk is not on, turn it on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (!(regval & TWL4030_GPBR1_MADC_HFCLK_EN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) dev_info(&pdev->dev, "clk disabled, enabling\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) regval |= TWL4030_GPBR1_MADC_HFCLK_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, regval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) TWL4030_REG_GPBR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) dev_err(&pdev->dev, "unable to write reg GPBR1 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) TWL4030_REG_GPBR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) goto err_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) platform_set_drvdata(pdev, iio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) mutex_init(&madc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) twl4030_madc_threaded_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) IRQF_TRIGGER_RISING | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) "twl4030_madc", madc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) dev_err(&pdev->dev, "could not request irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) goto err_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) twl4030_madc = madc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) /* Configure MADC[3:6] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) ret = twl_i2c_read_u8(TWL_MODULE_USB, ®val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) TWL4030_USB_CARKIT_ANA_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) dev_err(&pdev->dev, "unable to read reg CARKIT_ANA_CTRL 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) TWL4030_USB_CARKIT_ANA_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) goto err_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) regval |= TWL4030_USB_SEL_MADC_MCPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) ret = twl_i2c_write_u8(TWL_MODULE_USB, regval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) TWL4030_USB_CARKIT_ANA_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) dev_err(&pdev->dev, "unable to write reg CARKIT_ANA_CTRL 0x%X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) TWL4030_USB_CARKIT_ANA_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) goto err_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) /* Enable 3v1 bias regulator for MADC[3:6] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) madc->usb3v1 = devm_regulator_get(madc->dev, "vusb3v1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (IS_ERR(madc->usb3v1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) goto err_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ret = regulator_enable(madc->usb3v1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) dev_err(madc->dev, "could not enable 3v1 bias regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) goto err_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) ret = iio_device_register(iio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) dev_err(&pdev->dev, "could not register iio device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) goto err_usb3v1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) err_usb3v1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) regulator_disable(madc->usb3v1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) err_i2c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) twl4030_madc_set_current_generator(madc, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) err_current_generator:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) twl4030_madc_set_power(madc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) static int twl4030_madc_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) struct iio_dev *iio_dev = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) struct twl4030_madc_data *madc = iio_priv(iio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) iio_device_unregister(iio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) twl4030_madc_set_current_generator(madc, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) twl4030_madc_set_power(madc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) regulator_disable(madc->usb3v1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) static const struct of_device_id twl_madc_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) { .compatible = "ti,twl4030-madc", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) MODULE_DEVICE_TABLE(of, twl_madc_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) static struct platform_driver twl4030_madc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) .probe = twl4030_madc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) .remove = twl4030_madc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) .name = "twl4030_madc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) .of_match_table = of_match_ptr(twl_madc_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) module_platform_driver(twl4030_madc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) MODULE_DESCRIPTION("TWL4030 ADC driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) MODULE_AUTHOR("J Keerthy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) MODULE_ALIAS("platform:twl4030_madc");