aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/intel_sst/intelmid_msic_control.c
diff options
context:
space:
mode:
authorDharageswari R <dharageswari.r@intel.com>2011-05-03 12:32:38 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-05-10 15:55:54 -0400
commit5572a44829f241e642e6c4ac120bf5e4d6295d8f (patch)
tree819efb6469f797b81858c376e2b42517ff2a9edd /drivers/staging/intel_sst/intelmid_msic_control.c
parentc3e25a24b55d206dfa261fb2c7bb29b09f7bcf9b (diff)
intel_sst: Line out support
This patch adds the support for lineout. The lineout input can be selected as any input channel by using a new alsa mixer kcontrol. Signed-off-by: Dharageswari R <dharageswari.r@intel.com> Signed-off-by: Ramesh Babu K V <ramesh.babu@intel.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/intel_sst/intelmid_msic_control.c')
-rw-r--r--drivers/staging/intel_sst/intelmid_msic_control.c254
1 files changed, 242 insertions, 12 deletions
diff --git a/drivers/staging/intel_sst/intelmid_msic_control.c b/drivers/staging/intel_sst/intelmid_msic_control.c
index bbe9ab20f96..10073c5b5f6 100644
--- a/drivers/staging/intel_sst/intelmid_msic_control.c
+++ b/drivers/staging/intel_sst/intelmid_msic_control.c
@@ -54,11 +54,8 @@ static int msic_init_card(void)
54 /*TI vibra w/a settings*/ 54 /*TI vibra w/a settings*/
55 {0x384, 0x80, 0}, 55 {0x384, 0x80, 0},
56 {0x385, 0x80, 0}, 56 {0x385, 0x80, 0},
57 /*vibra settings*/
58 {0x267, 0x00, 0}, 57 {0x267, 0x00, 0},
59 {0x26A, 0x10, 0},
60 {0x261, 0x00, 0}, 58 {0x261, 0x00, 0},
61 {0x264, 0x10, 0},
62 /* pcm port setting */ 59 /* pcm port setting */
63 {0x278, 0x00, 0}, 60 {0x278, 0x00, 0},
64 {0x27B, 0x01, 0}, 61 {0x27B, 0x01, 0},
@@ -80,14 +77,221 @@ static int msic_init_card(void)
80 {0x1e, 0x00, 0x00}, 77 {0x1e, 0x00, 0x00},
81 }; 78 };
82 snd_msic_ops.card_status = SND_CARD_INIT_DONE; 79 snd_msic_ops.card_status = SND_CARD_INIT_DONE;
83 sst_sc_reg_access(sc_access, PMIC_WRITE, 30); 80 sst_sc_reg_access(sc_access, PMIC_WRITE, 28);
84 snd_msic_ops.pb_on = 0; 81 snd_msic_ops.pb_on = 0;
82 snd_msic_ops.pbhs_on = 0;
85 snd_msic_ops.cap_on = 0; 83 snd_msic_ops.cap_on = 0;
86 snd_msic_ops.input_dev_id = DMIC; /*def dev*/ 84 snd_msic_ops.input_dev_id = DMIC; /*def dev*/
87 snd_msic_ops.output_dev_id = STEREO_HEADPHONE; 85 snd_msic_ops.output_dev_id = STEREO_HEADPHONE;
88 pr_debug("msic init complete!!\n"); 86 pr_debug("msic init complete!!\n");
89 return 0; 87 return 0;
90} 88}
89static int msic_line_out_restore(u8 value)
90{
91 struct sc_reg_access hs_drv_en[] = {
92 {0x25d, 0x03, 0x03},
93 };
94 struct sc_reg_access ep_drv_en[] = {
95 {0x25d, 0x40, 0x40},
96 };
97 struct sc_reg_access ihf_drv_en[] = {
98 {0x25d, 0x0c, 0x0c},
99 };
100 struct sc_reg_access vib1_drv_en[] = {
101 {0x25d, 0x10, 0x10},
102 };
103 struct sc_reg_access vib2_drv_en[] = {
104 {0x25d, 0x20, 0x20},
105 };
106 int retval = 0;
107
108 pr_debug("msic_lineout_restore_lineout_dev:%d\n", value);
109
110 switch (value) {
111 case HEADSET:
112 pr_debug("Selecting Lineout-HEADSET-restore\n");
113 if (snd_msic_ops.output_dev_id == STEREO_HEADPHONE)
114 retval = sst_sc_reg_access(hs_drv_en,
115 PMIC_READ_MODIFY, 1);
116 else
117 retval = sst_sc_reg_access(ep_drv_en,
118 PMIC_READ_MODIFY, 1);
119 break;
120 case IHF:
121 pr_debug("Selecting Lineout-IHF-restore\n");
122 retval = sst_sc_reg_access(ihf_drv_en, PMIC_READ_MODIFY, 1);
123 break;
124 case VIBRA1:
125 pr_debug("Selecting Lineout-Vibra1-restore\n");
126 retval = sst_sc_reg_access(vib1_drv_en, PMIC_READ_MODIFY, 1);
127 break;
128 case VIBRA2:
129 pr_debug("Selecting Lineout-VIBRA2-restore\n");
130 retval = sst_sc_reg_access(vib2_drv_en, PMIC_READ_MODIFY, 1);
131 break;
132 case NONE:
133 pr_debug("Selecting Lineout-NONE-restore\n");
134 break;
135 default:
136 return -EINVAL;
137 }
138 return retval;
139}
140static int msic_get_lineout_prvstate(void)
141{
142 struct sc_reg_access hs_ihf_drv[2] = {
143 {0x257, 0x0, 0x0},
144 {0x25d, 0x0, 0x0},
145 };
146 struct sc_reg_access vib1drv[2] = {
147 {0x264, 0x0, 0x0},
148 {0x25D, 0x0, 0x0},
149 };
150 struct sc_reg_access vib2drv[2] = {
151 {0x26A, 0x0, 0x0},
152 {0x25D, 0x0, 0x0},
153 };
154 int retval = 0, drv_en, dac_en, dev_id, mask;
155 for (dev_id = 0; dev_id < snd_msic_ops.line_out_names_cnt; dev_id++) {
156 switch (dev_id) {
157 case HEADSET:
158 pr_debug("msic_get_lineout_prvs_state: HEADSET\n");
159 sst_sc_reg_access(hs_ihf_drv, PMIC_READ, 2);
160
161 mask = (MASK0|MASK1);
162 dac_en = (hs_ihf_drv[0].value) & mask;
163
164 mask = ((MASK0|MASK1)|MASK6);
165 drv_en = (hs_ihf_drv[1].value) & mask;
166
167 if (dac_en && (!drv_en)) {
168 snd_msic_ops.prev_lineout_dev_id = HEADSET;
169 return retval;
170 }
171 break;
172 case IHF:
173 pr_debug("msic_get_lineout_prvstate: IHF\n");
174 sst_sc_reg_access(hs_ihf_drv, PMIC_READ, 2);
175
176 mask = (MASK2 | MASK3);
177 dac_en = (hs_ihf_drv[0].value) & mask;
178
179 mask = (MASK2 | MASK3);
180 drv_en = (hs_ihf_drv[1].value) & mask;
181
182 if (dac_en && (!drv_en)) {
183 snd_msic_ops.prev_lineout_dev_id = IHF;
184 return retval;
185 }
186 break;
187 case VIBRA1:
188 pr_debug("msic_get_lineout_prvstate: vibra1\n");
189 sst_sc_reg_access(vib1drv, PMIC_READ, 2);
190
191 mask = MASK1;
192 dac_en = (vib1drv[0].value) & mask;
193
194 mask = MASK4;
195 drv_en = (vib1drv[1].value) & mask;
196
197 if (dac_en && (!drv_en)) {
198 snd_msic_ops.prev_lineout_dev_id = VIBRA1;
199 return retval;
200 }
201 break;
202 case VIBRA2:
203 pr_debug("msic_get_lineout_prvstate: vibra2\n");
204 sst_sc_reg_access(vib2drv, PMIC_READ, 2);
205
206 mask = MASK1;
207 dac_en = (vib2drv[0].value) & mask;
208
209 mask = MASK5;
210 drv_en = ((vib2drv[1].value) & mask);
211
212 if (dac_en && (!drv_en)) {
213 snd_msic_ops.prev_lineout_dev_id = VIBRA2;
214 return retval;
215 }
216 break;
217 case NONE:
218 pr_debug("msic_get_lineout_prvstate: NONE\n");
219 snd_msic_ops.prev_lineout_dev_id = NONE;
220 return retval;
221 default:
222 pr_debug("Invalid device id\n");
223 snd_msic_ops.prev_lineout_dev_id = NONE;
224 return -EINVAL;
225 }
226 }
227 return retval;
228}
229static int msic_set_selected_lineout_dev(u8 value)
230{
231 struct sc_reg_access lout_hs[] = {
232 {0x25e, 0x33, 0xFF},
233 {0x25d, 0x0, 0x43},
234 };
235 struct sc_reg_access lout_ihf[] = {
236 {0x25e, 0x55, 0xff},
237 {0x25d, 0x0, 0x0c},
238 };
239 struct sc_reg_access lout_vibra1[] = {
240
241 {0x25e, 0x61, 0xff},
242 {0x25d, 0x0, 0x10},
243 };
244 struct sc_reg_access lout_vibra2[] = {
245
246 {0x25e, 0x16, 0xff},
247 {0x25d, 0x0, 0x20},
248 };
249 struct sc_reg_access lout_def[] = {
250 {0x25e, 0x66, 0x0},
251 };
252 int retval = 0;
253
254 pr_debug("msic_set_selected_lineout_dev:%d\n", value);
255 msic_get_lineout_prvstate();
256 msic_line_out_restore(snd_msic_ops.prev_lineout_dev_id);
257 snd_msic_ops.lineout_dev_id = value;
258
259 switch (value) {
260 case HEADSET:
261 pr_debug("Selecting Lineout-HEADSET\n");
262 if (snd_msic_ops.pb_on)
263 retval = sst_sc_reg_access(lout_hs,
264 PMIC_READ_MODIFY, 2);
265 break;
266 case IHF:
267 pr_debug("Selecting Lineout-IHF\n");
268 if (snd_msic_ops.pb_on)
269 retval = sst_sc_reg_access(lout_ihf,
270 PMIC_READ_MODIFY, 2);
271 break;
272 case VIBRA1:
273 pr_debug("Selecting Lineout-Vibra1\n");
274 if (snd_msic_ops.pb_on)
275 retval = sst_sc_reg_access(lout_vibra1,
276 PMIC_READ_MODIFY, 2);
277 break;
278 case VIBRA2:
279 pr_debug("Selecting Lineout-VIBRA2\n");
280 if (snd_msic_ops.pb_on)
281 retval = sst_sc_reg_access(lout_vibra2,
282 PMIC_READ_MODIFY, 2);
283 break;
284 case NONE:
285 pr_debug("Selecting Lineout-NONE\n");
286 retval = sst_sc_reg_access(lout_def,
287 PMIC_WRITE, 1);
288 break;
289 default:
290 return -EINVAL;
291 }
292 return retval;
293}
294
91 295
92static int msic_power_up_pb(unsigned int device) 296static int msic_power_up_pb(unsigned int device)
93{ 297{
@@ -161,12 +365,12 @@ static int msic_power_up_pb(unsigned int device)
161 struct sc_reg_access vib1_en[] = { 365 struct sc_reg_access vib1_en[] = {
162 /* enable driver, ADC */ 366 /* enable driver, ADC */
163 {0x25D, 0x10, 0x10}, 367 {0x25D, 0x10, 0x10},
164 {0x264, 0x02, 0x02}, 368 {0x264, 0x02, 0x82},
165 }; 369 };
166 struct sc_reg_access vib2_en[] = { 370 struct sc_reg_access vib2_en[] = {
167 /* enable driver, ADC */ 371 /* enable driver, ADC */
168 {0x25D, 0x20, 0x20}, 372 {0x25D, 0x20, 0x20},
169 {0x26A, 0x02, 0x02}, 373 {0x26A, 0x02, 0x82},
170 }; 374 };
171 struct sc_reg_access pcm2_en[] = { 375 struct sc_reg_access pcm2_en[] = {
172 /* enable pcm 2 */ 376 /* enable pcm 2 */
@@ -187,6 +391,8 @@ static int msic_power_up_pb(unsigned int device)
187 msleep(1); 391 msleep(1);
188 switch (device) { 392 switch (device) {
189 case SND_SST_DEVICE_HEADSET: 393 case SND_SST_DEVICE_HEADSET:
394 snd_msic_ops.pb_on = 1;
395 snd_msic_ops.pbhs_on = 1;
190 if (snd_msic_ops.output_dev_id == STEREO_HEADPHONE) { 396 if (snd_msic_ops.output_dev_id == STEREO_HEADPHONE) {
191 sst_sc_reg_access(vhs, PMIC_WRITE, 2); 397 sst_sc_reg_access(vhs, PMIC_WRITE, 2);
192 sst_sc_reg_access(hsdac, PMIC_READ_MODIFY, 2); 398 sst_sc_reg_access(hsdac, PMIC_READ_MODIFY, 2);
@@ -197,22 +403,31 @@ static int msic_power_up_pb(unsigned int device)
197 sst_sc_reg_access(hs_filter, PMIC_WRITE, 2); 403 sst_sc_reg_access(hs_filter, PMIC_WRITE, 2);
198 sst_sc_reg_access(ep_enable, PMIC_READ_MODIFY, 3); 404 sst_sc_reg_access(ep_enable, PMIC_READ_MODIFY, 3);
199 } 405 }
200 snd_msic_ops.pb_on = 1; 406 if (snd_msic_ops.lineout_dev_id == HEADSET)
407 msic_set_selected_lineout_dev(HEADSET);
201 break; 408 break;
202
203 case SND_SST_DEVICE_IHF: 409 case SND_SST_DEVICE_IHF:
410 snd_msic_ops.pb_on = 1;
204 sst_sc_reg_access(vihf, PMIC_WRITE, 1); 411 sst_sc_reg_access(vihf, PMIC_WRITE, 1);
205 sst_sc_reg_access(ihf_filter, PMIC_READ_MODIFY, 3); 412 sst_sc_reg_access(ihf_filter, PMIC_READ_MODIFY, 3);
206 sst_sc_reg_access(ihf_en, PMIC_READ_MODIFY, 1); 413 sst_sc_reg_access(ihf_en, PMIC_READ_MODIFY, 1);
207 sst_sc_reg_access(ihf_unmute, PMIC_READ_MODIFY, 2); 414 sst_sc_reg_access(ihf_unmute, PMIC_READ_MODIFY, 2);
415 if (snd_msic_ops.lineout_dev_id == IHF)
416 msic_set_selected_lineout_dev(IHF);
208 break; 417 break;
209 418
210 case SND_SST_DEVICE_VIBRA: 419 case SND_SST_DEVICE_VIBRA:
420 snd_msic_ops.pb_on = 1;
211 sst_sc_reg_access(vib1_en, PMIC_READ_MODIFY, 2); 421 sst_sc_reg_access(vib1_en, PMIC_READ_MODIFY, 2);
422 if (snd_msic_ops.lineout_dev_id == VIBRA1)
423 msic_set_selected_lineout_dev(VIBRA1);
212 break; 424 break;
213 425
214 case SND_SST_DEVICE_HAPTIC: 426 case SND_SST_DEVICE_HAPTIC:
427 snd_msic_ops.pb_on = 1;
215 sst_sc_reg_access(vib2_en, PMIC_READ_MODIFY, 2); 428 sst_sc_reg_access(vib2_en, PMIC_READ_MODIFY, 2);
429 if (snd_msic_ops.lineout_dev_id == VIBRA2)
430 msic_set_selected_lineout_dev(VIBRA2);
216 break; 431 break;
217 432
218 default: 433 default:
@@ -310,6 +525,7 @@ static int msic_power_down(void)
310 }; 525 };
311 526
312 pr_debug("powering dn msic\n"); 527 pr_debug("powering dn msic\n");
528 snd_msic_ops.pbhs_on = 0;
313 snd_msic_ops.pb_on = 0; 529 snd_msic_ops.pb_on = 0;
314 snd_msic_ops.cap_on = 0; 530 snd_msic_ops.cap_on = 0;
315 sst_sc_reg_access(power_dn, PMIC_WRITE, 3); 531 sst_sc_reg_access(power_dn, PMIC_WRITE, 3);
@@ -348,15 +564,22 @@ static int msic_power_down_pb(unsigned int device)
348 struct sc_reg_access vib2_off[] = { 564 struct sc_reg_access vib2_off[] = {
349 {0x26A, 0x00, 0x82}, 565 {0x26A, 0x00, 0x82},
350 }; 566 };
567 struct sc_reg_access lout_off[] = {
568 {0x25e, 0x66, 0x00},
569 };
570
571
351 572
352 pr_debug("powering dn pb for device %d\n", device); 573 pr_debug("powering dn pb for device %d\n", device);
353 switch (device) { 574 switch (device) {
354 case SND_SST_DEVICE_HEADSET: 575 case SND_SST_DEVICE_HEADSET:
355 snd_msic_ops.pb_on = 0; 576 snd_msic_ops.pbhs_on = 0;
356 sst_sc_reg_access(hs_mute, PMIC_READ_MODIFY, 3); 577 sst_sc_reg_access(hs_mute, PMIC_READ_MODIFY, 3);
357 drv_enable[0].mask = 0x43; 578 drv_enable[0].mask = 0x43;
358 sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1); 579 sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
359 sst_sc_reg_access(hs_off, PMIC_READ_MODIFY, 2); 580 sst_sc_reg_access(hs_off, PMIC_READ_MODIFY, 2);
581 if (snd_msic_ops.lineout_dev_id == HEADSET)
582 sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
360 break; 583 break;
361 584
362 case SND_SST_DEVICE_IHF: 585 case SND_SST_DEVICE_IHF:
@@ -364,18 +587,24 @@ static int msic_power_down_pb(unsigned int device)
364 drv_enable[0].mask = 0x0C; 587 drv_enable[0].mask = 0x0C;
365 sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1); 588 sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
366 sst_sc_reg_access(ihf_off, PMIC_READ_MODIFY, 2); 589 sst_sc_reg_access(ihf_off, PMIC_READ_MODIFY, 2);
590 if (snd_msic_ops.lineout_dev_id == IHF)
591 sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
367 break; 592 break;
368 593
369 case SND_SST_DEVICE_VIBRA: 594 case SND_SST_DEVICE_VIBRA:
370 sst_sc_reg_access(vib1_off, PMIC_READ_MODIFY, 2); 595 sst_sc_reg_access(vib1_off, PMIC_READ_MODIFY, 1);
371 drv_enable[0].mask = 0x10; 596 drv_enable[0].mask = 0x10;
372 sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1); 597 sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
598 if (snd_msic_ops.lineout_dev_id == VIBRA1)
599 sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
373 break; 600 break;
374 601
375 case SND_SST_DEVICE_HAPTIC: 602 case SND_SST_DEVICE_HAPTIC:
376 sst_sc_reg_access(vib2_off, PMIC_READ_MODIFY, 2); 603 sst_sc_reg_access(vib2_off, PMIC_READ_MODIFY, 1);
377 drv_enable[0].mask = 0x20; 604 drv_enable[0].mask = 0x20;
378 sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1); 605 sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
606 if (snd_msic_ops.lineout_dev_id == VIBRA2)
607 sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
379 break; 608 break;
380 } 609 }
381 return 0; 610 return 0;
@@ -414,7 +643,7 @@ static int msic_set_selected_output_dev(u8 value)
414 643
415 pr_debug("msic set selected output:%d\n", value); 644 pr_debug("msic set selected output:%d\n", value);
416 snd_msic_ops.output_dev_id = value; 645 snd_msic_ops.output_dev_id = value;
417 if (snd_msic_ops.pb_on) 646 if (snd_msic_ops.pbhs_on)
418 msic_power_up_pb(SND_SST_DEVICE_HEADSET); 647 msic_power_up_pb(SND_SST_DEVICE_HEADSET);
419 return retval; 648 return retval;
420} 649}
@@ -494,6 +723,7 @@ static int msic_get_vol(int dev_id, int *value)
494struct snd_pmic_ops snd_msic_ops = { 723struct snd_pmic_ops snd_msic_ops = {
495 .set_input_dev = msic_set_selected_input_dev, 724 .set_input_dev = msic_set_selected_input_dev,
496 .set_output_dev = msic_set_selected_output_dev, 725 .set_output_dev = msic_set_selected_output_dev,
726 .set_lineout_dev = msic_set_selected_lineout_dev,
497 .set_mute = msic_set_mute, 727 .set_mute = msic_set_mute,
498 .get_mute = msic_get_mute, 728 .get_mute = msic_get_mute,
499 .set_vol = msic_set_vol, 729 .set_vol = msic_set_vol,