]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/intel_sst/intelmid_pvt.c
Merge branches 'msm-core' and 'msm-mmc' into for-next
[mv-sheeva.git] / drivers / staging / intel_sst / intelmid_pvt.c
1 /*
2  *   intelmid_pvt.h - Intel Sound card driver for MID
3  *
4  *  Copyright (C) 2008-10 Intel Corp
5  *  Authors:    Harsha Priya <priya.harsha@intel.com>
6  *              Vinod Koul <vinod.koul@intel.com>
7  *              KP Jeeja <jeeja.kp@intel.com>
8  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; version 2 of the License.
13  *
14  *  This program is distributed in the hope that it will be useful, but
15  *  WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License along
20  *  with this program; if not, write to the Free Software Foundation, Inc.,
21  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22  *
23  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24  * ALSA driver for Intel MID sound card chipset - holding private functions
25  */
26 #include <linux/io.h>
27 #include <asm/intel_scu_ipc.h>
28 #include <sound/core.h>
29 #include <sound/control.h>
30 #include <sound/pcm.h>
31 #include "jack.h"
32 #include "intel_sst.h"
33 #include "intel_sst_ioctl.h"
34 #include "intelmid_snd_control.h"
35 #include "intelmid.h"
36
37
38 void period_elapsed(void *mad_substream)
39 {
40         struct snd_pcm_substream *substream = mad_substream;
41         struct mad_stream_pvt *stream;
42
43
44
45         if (!substream || !substream->runtime)
46                 return;
47         stream = substream->runtime->private_data;
48         if (!stream)
49                 return;
50
51         if (stream->stream_status != RUNNING)
52                 return;
53         pr_debug("sst: calling period elapsed\n");
54         snd_pcm_period_elapsed(substream);
55         return;
56 }
57
58
59 int snd_intelmad_alloc_stream(struct snd_pcm_substream *substream)
60 {
61         struct snd_intelmad *intelmaddata = snd_pcm_substream_chip(substream);
62         struct mad_stream_pvt *stream = substream->runtime->private_data;
63         struct snd_sst_stream_params param = {{{0,},},};
64         struct snd_sst_params str_params = {0};
65         int ret_val;
66
67         /* set codec params and inform SST driver the same */
68
69         param.uc.pcm_params.codec = SST_CODEC_TYPE_PCM;
70         param.uc.pcm_params.num_chan = (u8) substream->runtime->channels;
71         param.uc.pcm_params.pcm_wd_sz = substream->runtime->sample_bits;
72         param.uc.pcm_params.reserved = 0;
73         param.uc.pcm_params.sfreq = substream->runtime->rate;
74         param.uc.pcm_params.ring_buffer_size =
75                                         snd_pcm_lib_buffer_bytes(substream);
76         param.uc.pcm_params.period_count = substream->runtime->period_size;
77         param.uc.pcm_params.ring_buffer_addr =
78                                 virt_to_phys(substream->runtime->dma_area);
79         pr_debug("sst: period_cnt = %d\n", param.uc.pcm_params.period_count);
80         pr_debug("sst: sfreq= %d, wd_sz = %d\n",
81                  param.uc.pcm_params.sfreq, param.uc.pcm_params.pcm_wd_sz);
82
83         str_params.sparams = param;
84         str_params.codec = SST_CODEC_TYPE_PCM;
85
86         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
87                 str_params.ops = STREAM_OPS_PLAYBACK;
88                 pr_debug("sst: Playbck stream,Device %d\n", stream->device);
89         } else {
90                 str_params.ops = STREAM_OPS_CAPTURE;
91                 stream->device = SND_SST_DEVICE_CAPTURE;
92                 pr_debug("sst: Capture stream,Device %d\n", stream->device);
93         }
94         str_params.device_type = stream->device;
95         ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_ALLOC,
96                                         &str_params);
97         pr_debug("sst: SST_SND_PLAY/CAPTURE ret_val = %x\n",
98                         ret_val);
99         if (ret_val < 0)
100                 return ret_val;
101
102         stream->stream_info.str_id = ret_val;
103         stream->stream_status = INIT;
104         stream->stream_info.buffer_ptr = 0;
105         pr_debug("sst: str id :  %d\n", stream->stream_info.str_id);
106
107         return ret_val;
108 }
109
110 int snd_intelmad_init_stream(struct snd_pcm_substream *substream)
111 {
112         struct mad_stream_pvt *stream = substream->runtime->private_data;
113         struct snd_intelmad *intelmaddata = snd_pcm_substream_chip(substream);
114         int ret_val;
115
116         pr_debug("sst: setting buffer ptr param\n");
117         stream->stream_info.period_elapsed = period_elapsed;
118         stream->stream_info.mad_substream = substream;
119         stream->stream_info.buffer_ptr = 0;
120         stream->stream_info.sfreq = substream->runtime->rate;
121         ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_STREAM_INIT,
122                                         &stream->stream_info);
123         if (ret_val)
124                 pr_err("sst: control_set ret error %d\n", ret_val);
125         return ret_val;
126
127 }
128
129
130 /**
131  * sst_sc_reg_access - IPC read/write wrapper
132  *
133  * @sc_access:  array of data, addresses and mask
134  * @type: operation type
135  * @num_val: number of reg to opertae on
136  *
137  * Reads/writes/read-modify operations on registers accessed through SCU (sound
138  * card and few SST DSP regsisters that are not accissible to IA)
139  */
140 int sst_sc_reg_access(struct sc_reg_access *sc_access,
141                                         int type, int num_val)
142 {
143         int i, retval = 0;
144         if (type == PMIC_WRITE) {
145                 for (i = 0; i < num_val; i++) {
146                         retval = intel_scu_ipc_iowrite8(sc_access[i].reg_addr,
147                                                         sc_access[i].value);
148                         if (retval) {
149                                 pr_err("sst: IPC write failed!!! %d\n", retval);
150                                 return retval;
151                         }
152                 }
153         } else if (type == PMIC_READ) {
154                 for (i = 0; i < num_val; i++) {
155                         retval = intel_scu_ipc_ioread8(sc_access[i].reg_addr,
156                                                         &(sc_access[i].value));
157                         if (retval) {
158                                 pr_err("sst: IPC read failed!!!!!%d\n", retval);
159                                 return retval;
160                         }
161                 }
162         } else {
163                 for (i = 0; i < num_val; i++) {
164                         retval = intel_scu_ipc_update_register(
165                                 sc_access[i].reg_addr, sc_access[i].value,
166                                 sc_access[i].mask);
167                         if (retval) {
168                                 pr_err("sst: IPC Modify failed!!!%d\n", retval);
169                                 return retval;
170                         }
171                 }
172         }
173         return retval;
174 }