staging:iio:trigger handle name attr in core, remove old alloc and register any contr...
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / intel_sst / intelmid_adc_control.h
blob65d5c3988762cf390bcbd3494e53fb958ed7d4af
1 #ifndef __INTELMID_ADC_CONTROL_H__
2 #define __INTELMID_ADC_CONTROL_H_
3 /*
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 */
52 /**
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
58 * Can sleep
60 static inline int configure_adc(int val)
62 int ret;
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);
68 if (ret)
69 return ret;
71 if (val)
72 /* Enable and start the ADC */
73 sc_access.value |= (MSIC_ADC_ENBL | MSIC_ADC_START);
74 else
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);
81 /**
82 * reset_stopbit - sets the stop bit to 0 on the given channel
83 * @addr: address of the channel
85 * Can sleep
87 static inline int reset_stopbit(uint16_t addr)
89 int ret;
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);
93 if (ret)
94 return ret;
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.
109 * Context: can sleep
112 static inline int find_free_channel(void)
114 int ret;
115 int i;
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);
122 if (ret)
123 return ret;
125 if ((sc_access.value & MSIC_ADC_ENBL) == 0)
126 return 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);
133 if (ret)
134 return ret;
136 if (sc_access.value & MSIC_STOPBIT_MASK) {
137 ret = i;
138 break;
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;
153 int ret;
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);
169 if (ret)
170 return ret;
172 /* Index of the first free channel */
173 base_addr++;
174 channel_index++;
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);
182 if (ret) {
183 pr_err("unable to enable ADC");
184 return ret;
187 chnl_addr = ADC_DATA_START_ADDR + 2 * channel_index;
188 pr_debug("mid_initialize : %x", chnl_addr);
189 configure_adc(1);
190 return chnl_addr;
192 #endif