1 #ifndef __INTELMID_ADC_CONTROL_H__
2 #define __INTELMID_ADC_CONTROL_H_
4 * intelmid_adc_control.h - Intel SST Driver for audio engine
6 * Copyright (C) 2008-10 Intel Corporation
7 * Authors: R Durgadadoss <r.durgadoss@intel.com>
8 * Dharageswari R <dharageswari.r@intel.com>
9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2 of the License.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26 * Common private ADC declarations for SST
30 #define MSIC_ADC1CNTL1 0x1C0
31 #define MSIC_ADC_ENBL 0x10
32 #define MSIC_ADC_START 0x08
34 #define MSIC_ADC1CNTL3 0x1C2
35 #define MSIC_ADCTHERM_ENBL 0x04
36 #define MSIC_ADCRRDATA_ENBL 0x05
38 #define MSIC_STOPBIT_MASK 16
39 #define MSIC_ADCTHERM_MASK 4
41 #define ADC_CHANLS_MAX 15 /* Number of ADC channels */
42 #define ADC_LOOP_MAX (ADC_CHANLS_MAX - 1)
44 /* ADC channel code values */
45 #define AUDIO_DETECT_CODE 0x06
47 /* ADC base addresses */
48 #define ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */
49 #define ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */
53 * configure_adc - enables/disables the ADC for conversion
54 * @val: zero: disables the ADC non-zero:enables the ADC
56 * Enable/Disable the ADC depending on the argument
60 static inline int configure_adc(int val)
63 struct sc_reg_access sc_access = {0,};
66 sc_access.reg_addr = MSIC_ADC1CNTL1;
67 ret = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
72 /* Enable and start the ADC */
73 sc_access.value |= (MSIC_ADC_ENBL | MSIC_ADC_START);
75 /* Just stop the ADC */
76 sc_access.value &= (~MSIC_ADC_START);
77 sc_access.reg_addr = MSIC_ADC1CNTL1;
78 return sst_sc_reg_access(&sc_access, PMIC_WRITE, 1);
82 * reset_stopbit - sets the stop bit to 0 on the given channel
83 * @addr: address of the channel
87 static inline int reset_stopbit(uint16_t addr)
90 struct sc_reg_access sc_access = {0,};
91 sc_access.reg_addr = addr;
92 ret = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
95 /* Set the stop bit to zero */
96 sc_access.reg_addr = addr;
97 sc_access.value = (sc_access.value) & 0xEF;
98 return sst_sc_reg_access(&sc_access, PMIC_WRITE, 1);
102 * find_free_channel - finds an empty channel for conversion
104 * If the ADC is not enabled then start using 0th channel
105 * itself. Otherwise find an empty channel by looking for a
106 * channel in which the stopbit is set to 1. returns the index
107 * of the first free channel if succeeds or an error code.
112 static inline int find_free_channel(void)
117 struct sc_reg_access sc_access = {0,};
119 /* check whether ADC is enabled */
120 sc_access.reg_addr = MSIC_ADC1CNTL1;
121 ret = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
125 if ((sc_access.value & MSIC_ADC_ENBL) == 0)
128 /* ADC is already enabled; Looking for an empty channel */
129 for (i = 0; i < ADC_CHANLS_MAX; i++) {
131 sc_access.reg_addr = ADC_CHNL_START_ADDR + i;
132 ret = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
136 if (sc_access.value & MSIC_STOPBIT_MASK) {
141 return (ret > ADC_LOOP_MAX) ? (-EINVAL) : ret;
145 * mid_initialize_adc - initializing the ADC
146 * @dev: our device structure
148 * Initialize the ADC for reading thermistor values. Can sleep.
150 static inline int mid_initialize_adc(void)
152 int base_addr, chnl_addr;
154 static int channel_index;
155 struct sc_reg_access sc_access = {0,};
157 /* Index of the first channel in which the stop bit is set */
158 channel_index = find_free_channel();
159 if (channel_index < 0) {
160 pr_err("No free ADC channels");
161 return channel_index;
164 base_addr = ADC_CHNL_START_ADDR + channel_index;
166 if (!(channel_index == 0 || channel_index == ADC_LOOP_MAX)) {
167 /* Reset stop bit for channels other than 0 and 12 */
168 ret = reset_stopbit(base_addr);
172 /* Index of the first free channel */
177 /* Since this is the last channel, set the stop bit
178 to 1 by ORing the DIE_SENSOR_CODE with 0x10 */
179 sc_access.reg_addr = base_addr;
180 sc_access.value = AUDIO_DETECT_CODE | 0x10;
181 ret = sst_sc_reg_access(&sc_access, PMIC_WRITE, 1);
183 pr_err("unable to enable ADC");
187 chnl_addr = ADC_DATA_START_ADDR + 2 * channel_index;
188 pr_debug("mid_initialize : %x", chnl_addr);