~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/staging/intel_sst/intelmid_adc_control.h

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef __INTELMID_ADC_CONTROL_H__
 
2
#define __INTELMID_ADC_CONTROL_H_
 
3
/*
 
4
 *  intelmid_adc_control.h - Intel SST Driver for audio engine
 
5
 *
 
6
 *  Copyright (C) 2008-10 Intel Corporation
 
7
 *  Authors:    R Durgadadoss <r.durgadoss@intel.com>
 
8
 *              Dharageswari R <dharageswari.r@intel.com>
 
9
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
10
 *
 
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.
 
14
 *
 
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.
 
19
 *
 
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.
 
23
 *
 
24
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
25
 *
 
26
 *  Common private ADC declarations for SST
 
27
 */
 
28
 
 
29
 
 
30
#define MSIC_ADC1CNTL1          0x1C0
 
31
#define MSIC_ADC_ENBL           0x10
 
32
#define MSIC_ADC_START          0x08
 
33
 
 
34
#define MSIC_ADC1CNTL3          0x1C2
 
35
#define MSIC_ADCTHERM_ENBL      0x04
 
36
#define MSIC_ADCRRDATA_ENBL     0x05
 
37
 
 
38
#define MSIC_STOPBIT_MASK       16
 
39
#define MSIC_ADCTHERM_MASK      4
 
40
 
 
41
#define ADC_CHANLS_MAX          15 /* Number of ADC channels */
 
42
#define ADC_LOOP_MAX            (ADC_CHANLS_MAX - 1)
 
43
 
 
44
/* ADC channel code values */
 
45
#define AUDIO_DETECT_CODE       0x06
 
46
 
 
47
/* ADC base addresses */
 
48
#define ADC_CHNL_START_ADDR     0x1C5   /* increments by 1 */
 
49
#define ADC_DATA_START_ADDR     0x1D4   /* increments by 2 */
 
50
 
 
51
 
 
52
/**
 
53
 * configure_adc - enables/disables the ADC for conversion
 
54
 * @val: zero: disables the ADC non-zero:enables the ADC
 
55
 *
 
56
 * Enable/Disable the ADC depending on the argument
 
57
 *
 
58
 * Can sleep
 
59
 */
 
60
static inline int configure_adc(int val)
 
61
{
 
62
        int ret;
 
63
        struct sc_reg_access sc_access = {0,};
 
64
 
 
65
 
 
66
        sc_access.reg_addr = MSIC_ADC1CNTL1;
 
67
        ret = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
 
68
        if (ret)
 
69
                return ret;
 
70
 
 
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);
 
79
}
 
80
 
 
81
/**
 
82
 * reset_stopbit - sets the stop bit to 0 on the given channel
 
83
 * @addr: address of the channel
 
84
 *
 
85
 * Can sleep
 
86
 */
 
87
static inline int reset_stopbit(uint16_t addr)
 
88
{
 
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);
 
99
}
 
100
 
 
101
/**
 
102
 * find_free_channel - finds an empty channel for conversion
 
103
 *
 
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.
 
108
 *
 
109
 * Context: can sleep
 
110
 *
 
111
 */
 
112
static inline int find_free_channel(void)
 
113
{
 
114
        int ret;
 
115
        int i;
 
116
 
 
117
        struct sc_reg_access sc_access = {0,};
 
118
 
 
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;
 
124
 
 
125
        if ((sc_access.value & MSIC_ADC_ENBL) == 0)
 
126
                return 0;
 
127
 
 
128
        /* ADC is already enabled; Looking for an empty channel */
 
129
        for (i = 0; i < ADC_CHANLS_MAX; i++) {
 
130
 
 
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;
 
135
 
 
136
                if (sc_access.value & MSIC_STOPBIT_MASK) {
 
137
                        ret = i;
 
138
                        break;
 
139
                }
 
140
        }
 
141
        return (ret > ADC_LOOP_MAX) ? (-EINVAL) : ret;
 
142
}
 
143
 
 
144
/**
 
145
 * mid_initialize_adc - initializing the ADC
 
146
 * @dev: our device structure
 
147
 *
 
148
 * Initialize the ADC for reading thermistor values. Can sleep.
 
149
 */
 
150
static inline int mid_initialize_adc(void)
 
151
{
 
152
        int base_addr, chnl_addr;
 
153
        int ret;
 
154
        static int channel_index;
 
155
        struct sc_reg_access sc_access = {0,};
 
156
 
 
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;
 
162
        }
 
163
 
 
164
        base_addr = ADC_CHNL_START_ADDR + channel_index;
 
165
 
 
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;
 
171
 
 
172
                /* Index of the first free channel */
 
173
                base_addr++;
 
174
                channel_index++;
 
175
        }
 
176
 
 
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;
 
185
        }
 
186
 
 
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;
 
191
}
 
192
#endif
 
193