fujitsu-laptop: fix compiler warning on pnp_ids
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / intel_sst / intelmid_msic_control.c
blob4d1755efceef242e3e9dda9a613bd37abcb1c00d
1 /*
2 * intelmid_vm_control.c - Intel Sound card driver for MID
4 * Copyright (C) 2010 Intel Corp
5 * Authors: Vinod Koul <vinod.koul@intel.com>
7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 * This file contains the control operations of msic vendors
27 #include <linux/pci.h>
28 #include <linux/file.h>
29 #include "intel_sst.h"
30 #include "intel_sst_ioctl.h"
31 #include "intelmid_snd_control.h"
33 static int msic_init_card(void)
35 struct sc_reg_access sc_access[] = {
36 /* dmic configuration */
37 {0x241, 0x85, 0},
38 {0x242, 0x02, 0},
39 /* audio paths config */
40 {0x24C, 0x10, 0},
41 {0x24D, 0x32, 0},
42 /* PCM2 interface slots */
43 /* preconfigured slots for 0-5 both tx, rx */
44 {0x272, 0x10, 0},
45 {0x273, 0x32, 0},
46 {0x274, 0xFF, 0},
47 {0x275, 0x10, 0},
48 {0x276, 0x32, 0},
49 {0x277, 0x54, 0},
50 /*Sinc5 decimator*/
51 {0x24E, 0x28, 0},
52 /*TI vibra w/a settings*/
53 {0x384, 0x80, 0},
54 {0x385, 0x80, 0},
55 /*vibra settings*/
56 {0x267, 0x00, 0},
57 {0x26A, 0x10, 0},
58 {0x261, 0x00, 0},
59 {0x264, 0x10, 0},
60 /* pcm port setting */
61 {0x278, 0x00, 0},
62 {0x27B, 0x01, 0},
63 {0x27C, 0x0a, 0},
64 /* Set vol HSLRVOLCTRL, IHFVOL */
65 {0x259, 0x04, 0},
66 {0x25A, 0x04, 0},
67 {0x25B, 0x04, 0},
68 {0x25C, 0x04, 0},
69 /* HSEPRXCTRL Enable the headset left and right FIR filters */
70 {0x250, 0x30, 0},
71 /* HSMIXER */
72 {0x256, 0x11, 0},
73 /* amic configuration */
74 {0x249, 0x09, 0x0},
75 {0x24A, 0x09, 0x0},
76 /* unmask ocaudio/accdet interrupts */
77 {0x1d, 0x00, 0x00},
78 {0x1e, 0x00, 0x00},
80 snd_msic_ops.card_status = SND_CARD_INIT_DONE;
81 sst_sc_reg_access(sc_access, PMIC_WRITE, 30);
82 snd_msic_ops.pb_on = 0;
83 snd_msic_ops.cap_on = 0;
84 snd_msic_ops.input_dev_id = DMIC; /*def dev*/
85 snd_msic_ops.output_dev_id = STEREO_HEADPHONE;
86 pr_debug("sst: msic init complete!!\n");
87 return 0;
90 static int msic_power_up_pb(unsigned int device)
92 struct sc_reg_access sc_access1[] = {
93 /* turn on the audio power supplies */
94 {0x0DB, 0x05, 0},
95 /* VHSP */
96 {0x0DC, 0xFF, 0},
97 /* VHSN */
98 {0x0DD, 0x3F, 0},
99 /* turn on PLL */
100 {0x240, 0x21, 0},
102 struct sc_reg_access sc_access2[] = {
103 /* disable driver */
104 {0x25D, 0x0, 0x43},
105 /* DAC CONFIG ; both HP, LP on */
106 {0x257, 0x03, 0x03},
108 struct sc_reg_access sc_access3[] = {
109 /* HSEPRXCTRL Enable the headset left and right FIR filters */
110 {0x250, 0x30, 0},
111 /* HSMIXER */
112 {0x256, 0x11, 0},
114 struct sc_reg_access sc_access4[] = {
115 /* enable driver */
116 {0x25D, 0x3, 0x3},
117 /* unmute the headset */
118 { 0x259, 0x80, 0x80},
119 { 0x25A, 0x80, 0x80},
121 struct sc_reg_access sc_access_vihf[] = {
122 /* VIHF ON */
123 {0x0C9, 0x2D, 0x00},
125 struct sc_reg_access sc_access22[] = {
126 /* disable driver */
127 {0x25D, 0x00, 0x0C},
128 /*Filer DAC enable*/
129 {0x251, 0x03, 0x03},
130 {0x257, 0x0C, 0x0C},
132 struct sc_reg_access sc_access32[] = {
133 /*enable drv*/
134 {0x25D, 0x0C, 0x0c},
136 struct sc_reg_access sc_access42[] = {
137 /*unmute headset*/
138 {0x25B, 0x80, 0x80},
139 {0x25C, 0x80, 0x80},
141 struct sc_reg_access sc_access23[] = {
142 /* disable driver */
143 {0x25D, 0x0, 0x43},
144 /* DAC CONFIG ; both HP, LP on */
145 {0x257, 0x03, 0x03},
147 struct sc_reg_access sc_access43[] = {
148 /* enable driver */
149 {0x25D, 0x40, 0x40},
150 /* unmute the headset */
151 { 0x259, 0x80, 0x80},
152 { 0x25A, 0x80, 0x80},
154 struct sc_reg_access sc_access_vib[] = {
155 /* enable driver, ADC */
156 {0x25D, 0x10, 0x10},
157 {0x264, 0x02, 0x02},
159 struct sc_reg_access sc_access_hap[] = {
160 /* enable driver, ADC */
161 {0x25D, 0x20, 0x20},
162 {0x26A, 0x02, 0x02},
164 struct sc_reg_access sc_access_pcm2[] = {
165 /* enable pcm 2 */
166 {0x27C, 0x1, 0x1},
168 int retval = 0;
170 if (snd_msic_ops.card_status == SND_CARD_UN_INIT) {
171 retval = msic_init_card();
172 if (retval)
173 return retval;
176 pr_debug("sst: powering up pb.... Device %d\n", device);
177 sst_sc_reg_access(sc_access1, PMIC_WRITE, 4);
178 switch (device) {
179 case SND_SST_DEVICE_HEADSET:
180 if (snd_msic_ops.output_dev_id == STEREO_HEADPHONE) {
181 sst_sc_reg_access(sc_access2, PMIC_READ_MODIFY, 2);
182 sst_sc_reg_access(sc_access3, PMIC_WRITE, 2);
183 sst_sc_reg_access(sc_access4, PMIC_READ_MODIFY, 3);
184 } else {
185 sst_sc_reg_access(sc_access23, PMIC_READ_MODIFY, 2);
186 sst_sc_reg_access(sc_access3, PMIC_WRITE, 2);
187 sst_sc_reg_access(sc_access43, PMIC_READ_MODIFY, 3);
189 snd_msic_ops.pb_on = 1;
190 break;
192 case SND_SST_DEVICE_IHF:
193 sst_sc_reg_access(sc_access_vihf, PMIC_WRITE, 1);
194 sst_sc_reg_access(sc_access22, PMIC_READ_MODIFY, 3);
195 sst_sc_reg_access(sc_access32, PMIC_READ_MODIFY, 1);
196 sst_sc_reg_access(sc_access42, PMIC_READ_MODIFY, 2);
197 break;
199 case SND_SST_DEVICE_VIBRA:
200 sst_sc_reg_access(sc_access_vib, PMIC_READ_MODIFY, 2);
201 break;
203 case SND_SST_DEVICE_HAPTIC:
204 sst_sc_reg_access(sc_access_hap, PMIC_READ_MODIFY, 2);
205 break;
207 default:
208 pr_warn("sst: Wrong Device %d, selected %d\n",
209 device, snd_msic_ops.output_dev_id);
211 return sst_sc_reg_access(sc_access_pcm2, PMIC_READ_MODIFY, 1);
214 static int msic_power_up_cp(unsigned int device)
216 struct sc_reg_access sc_access[] = {
217 /* turn on the audio power supplies */
218 {0x0DB, 0x05, 0},
219 /* VHSP */
220 {0x0DC, 0xFF, 0},
221 /* VHSN */
222 {0x0DD, 0x3F, 0},
223 /* turn on PLL */
224 {0x240, 0x21, 0},
226 /* Turn on DMIC supply */
227 {0x247, 0xA0, 0x0},
228 {0x240, 0x21, 0x0},
229 {0x24C, 0x10, 0x0},
231 /* mic demux enable */
232 {0x245, 0x3F, 0x0},
233 {0x246, 0x7, 0x0},
236 struct sc_reg_access sc_access_amic[] = {
237 /* turn on the audio power supplies */
238 {0x0DB, 0x05, 0},
239 /* VHSP */
240 {0x0DC, 0xFF, 0},
241 /* VHSN */
242 {0x0DD, 0x3F, 0},
243 /* turn on PLL */
244 {0x240, 0x21, 0},
245 /*ADC EN*/
246 {0x248, 0x05, 0x0},
247 {0x24C, 0x76, 0x0},
248 /*MIC EN*/
249 {0x249, 0x09, 0x0},
250 {0x24A, 0x09, 0x0},
251 /* Turn on AMIC supply */
252 {0x247, 0xFC, 0x0},
255 struct sc_reg_access sc_access2[] = {
256 /* enable pcm 2 */
257 {0x27C, 0x1, 0x1},
259 struct sc_reg_access sc_access3[] = {
260 /*wait for mic to stabalize before turning on audio channels*/
261 {0x24F, 0x3C, 0x0},
263 int retval = 0;
265 if (snd_msic_ops.card_status == SND_CARD_UN_INIT) {
266 retval = msic_init_card();
267 if (retval)
268 return retval;
271 pr_debug("sst: powering up cp....%d\n", snd_msic_ops.input_dev_id);
272 sst_sc_reg_access(sc_access2, PMIC_READ_MODIFY, 1);
273 snd_msic_ops.cap_on = 1;
274 if (snd_msic_ops.input_dev_id == AMIC)
275 sst_sc_reg_access(sc_access_amic, PMIC_WRITE, 9);
276 else
277 sst_sc_reg_access(sc_access, PMIC_WRITE, 9);
278 return sst_sc_reg_access(sc_access3, PMIC_WRITE, 1);
282 static int msic_power_down(void)
284 int retval = 0;
286 pr_debug("sst: powering dn msic\n");
287 snd_msic_ops.pb_on = 0;
288 snd_msic_ops.cap_on = 0;
289 return retval;
292 static int msic_power_down_pb(void)
294 int retval = 0;
296 pr_debug("sst: powering dn pb....\n");
297 snd_msic_ops.pb_on = 0;
298 return retval;
301 static int msic_power_down_cp(void)
303 int retval = 0;
305 pr_debug("sst: powering dn cp....\n");
306 snd_msic_ops.cap_on = 0;
307 return retval;
310 static int msic_set_selected_output_dev(u8 value)
312 int retval = 0;
314 pr_debug("sst: msic set selected output:%d\n", value);
315 snd_msic_ops.output_dev_id = value;
316 if (snd_msic_ops.pb_on)
317 msic_power_up_pb(SND_SST_DEVICE_HEADSET);
318 return retval;
321 static int msic_set_selected_input_dev(u8 value)
324 struct sc_reg_access sc_access_dmic[] = {
325 {0x24C, 0x10, 0x0},
327 struct sc_reg_access sc_access_amic[] = {
328 {0x24C, 0x76, 0x0},
331 int retval = 0;
333 pr_debug("sst: msic_set_selected_input_dev:%d\n", value);
334 snd_msic_ops.input_dev_id = value;
335 switch (value) {
336 case AMIC:
337 pr_debug("sst: Selecting AMIC1\n");
338 retval = sst_sc_reg_access(sc_access_amic, PMIC_WRITE, 1);
339 break;
340 case DMIC:
341 pr_debug("sst: Selecting DMIC1\n");
342 retval = sst_sc_reg_access(sc_access_dmic, PMIC_WRITE, 1);
343 break;
344 default:
345 return -EINVAL;
348 if (snd_msic_ops.cap_on)
349 retval = msic_power_up_cp(SND_SST_DEVICE_CAPTURE);
350 return retval;
353 static int msic_set_pcm_voice_params(void)
355 return 0;
358 static int msic_set_pcm_audio_params(int sfreq, int word_size, int num_channel)
360 return 0;
363 static int msic_set_audio_port(int status)
365 return 0;
368 static int msic_set_voice_port(int status)
370 return 0;
373 static int msic_set_mute(int dev_id, u8 value)
375 return 0;
378 static int msic_set_vol(int dev_id, int value)
380 return 0;
383 static int msic_get_mute(int dev_id, u8 *value)
385 return 0;
388 static int msic_get_vol(int dev_id, int *value)
390 return 0;
393 struct snd_pmic_ops snd_msic_ops = {
394 .set_input_dev = msic_set_selected_input_dev,
395 .set_output_dev = msic_set_selected_output_dev,
396 .set_mute = msic_set_mute,
397 .get_mute = msic_get_mute,
398 .set_vol = msic_set_vol,
399 .get_vol = msic_get_vol,
400 .init_card = msic_init_card,
401 .set_pcm_audio_params = msic_set_pcm_audio_params,
402 .set_pcm_voice_params = msic_set_pcm_voice_params,
403 .set_voice_port = msic_set_voice_port,
404 .set_audio_port = msic_set_audio_port,
405 .power_up_pmic_pb = msic_power_up_pb,
406 .power_up_pmic_cp = msic_power_up_cp,
407 .power_down_pmic_pb = msic_power_down_pb,
408 .power_down_pmic_cp = msic_power_down_cp,
409 .power_down_pmic = msic_power_down,