c3a80cabd3b7dccff1a500fff0c81195610504e5
[yamaha-mc1n2-audio.git] / yamaha-mc1n2-audio.c
1 /*
2  * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25
26 #include <linux/ioctl.h>
27
28 #define LOG_TAG "Yamaha-MC1N2-Audio"
29 #include <cutils/log.h>
30
31 #include <system/audio.h>
32
33 #include <yamaha-mc1n2-audio.h>
34
35 struct yamaha_mc1n2_audio_pdata *yamaha_mc1n2_audio_platforms[] = {
36         &galaxys2_pdata,
37 };
38
39 int yamaha_mc1n2_audio_platforms_count = sizeof(yamaha_mc1n2_audio_platforms) /
40         sizeof(struct yamaha_mc1n2_audio_pdata *);
41
42 /*
43  * IOCTL
44  */
45
46 int yamaha_mc1n2_audio_ioctl(struct yamaha_mc1n2_audio_pdata *pdata,
47         int command, struct mc1n2_ctrl_args *hw_ctrl)
48 {
49         char *hw_node = NULL;
50         int hw_fd = -1;
51         int rc = -1;
52
53         if(pdata == NULL)
54                 return -1;
55
56         hw_node = yamaha_mc1n2_audio_get_hw_node(pdata);
57         if(hw_node == NULL) {
58                 LOGE("%s: error, missing hw_node!", __func__);
59                 return -1;
60         }
61
62         hw_fd = open(hw_node, O_RDWR);
63         if(hw_fd < 0) {
64                 LOGE("%s: error, unable to open hw_node (fd is %d)!", __func__, hw_fd);
65                 return -1;
66         }
67
68         rc = ioctl(hw_fd, command, hw_ctrl);
69         if(rc < 0) {
70                 LOGE("%s: error, ioctl on hw_node failed (rc is %d)!", __func__, rc);
71                 return -1;
72         }
73
74         close(hw_fd);
75
76         return rc;
77 }
78
79 int yamaha_mc1n2_audio_ioctl_set_ctrl(struct yamaha_mc1n2_audio_pdata *pdata,
80         unsigned long command, void *data, unsigned long update_info)
81 {
82         struct mc1n2_ctrl_args hw_ctrl;
83
84         if(pdata == NULL)
85                 return -1;
86
87         memset(&hw_ctrl, 0, sizeof(hw_ctrl));
88         hw_ctrl.dCmd = command;
89         hw_ctrl.pvPrm = data;
90         hw_ctrl.dPrm = update_info;
91
92         return yamaha_mc1n2_audio_ioctl(pdata, MC1N2_IOCTL_SET_CTRL, &hw_ctrl);
93 }
94
95 int yamaha_mc1n2_audio_ioctl_notify(struct yamaha_mc1n2_audio_pdata *pdata,
96         unsigned long command)
97 {
98         struct mc1n2_ctrl_args hw_ctrl;
99
100         if(pdata == NULL)
101                 return -1;
102
103         memset(&hw_ctrl, 0, sizeof(hw_ctrl));
104         hw_ctrl.dCmd = command;
105
106         return yamaha_mc1n2_audio_ioctl(pdata, MC1N2_IOCTL_NOTIFY, &hw_ctrl);
107 }
108
109 /*
110  * Routines
111  */
112
113 int yamaha_mc1n2_audio_init(struct yamaha_mc1n2_audio_pdata *pdata)
114 {
115         struct yamaha_mc1n2_audio_params_init *params = NULL;
116         int rc = -1;
117
118         if(pdata == NULL || pdata->ops == NULL)
119                 return -1;
120
121         params = pdata->ops->params.init;
122         if(params == NULL)
123                 return -1;
124
125         rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_DAC,
126                 &params->dac_info, 0x07);
127         if(rc < 0) {
128                 LOGE("SET_DAC IOCTL failed, aborting!");
129                 return -1;
130         }
131
132         rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_ADC,
133                 &params->adc_info, 0x07);
134         if(rc < 0) {
135                 LOGE("SET_ADC IOCTL failed, aborting!");
136                 return -1;
137         }
138
139         rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_SP,
140                 &params->sp_info, 0x00);
141         if(rc < 0) {
142                 LOGE("SET_SP IOCTL failed, aborting!");
143                 return -1;
144         }
145
146         rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_PDM,
147                 &params->pdm_info, 0x7f);
148         if(rc < 0) {
149                 LOGE("SET_PDM IOCTL failed, aborting!");
150                 return -1;
151         }
152
153         rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_DNG,
154                 &params->dng_info, 0x3f3f3f);
155         if(rc < 0) {
156                 LOGE("SET_DNG IOCTL failed, aborting!");
157                 return -1;
158         }
159
160         rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_SYSEQ,
161                 &params->syseq_info, 0x03);
162         if(rc < 0) {
163                 LOGE("SET_SYSEQ IOCTL failed, aborting!");
164                 return -1;
165         }
166
167         return 0;
168 }
169
170 struct yamaha_mc1n2_audio_params_route *
171         yamaha_mc1n2_audio_params_route_find(struct yamaha_mc1n2_audio_pdata *pdata,
172         audio_devices_t device, enum yamaha_mc1n2_audio_direction direction)
173 {
174         struct yamaha_mc1n2_audio_params_route *params = NULL;
175         int params_count = 0;
176         int i;
177
178         if(pdata == NULL || pdata->ops == NULL)
179                 return NULL;
180
181         params = pdata->ops->params.routes;
182         params_count = pdata->ops->params.routes_count;
183         if(params == NULL || params_count <= 0)
184                 return NULL;
185
186         for(i=0 ; i < params_count ; i++) {
187                 if(params[i].device == device && params[i].direction == direction)
188                         return &params[i];
189         }
190
191         return NULL;
192 }
193
194 int yamaha_mc1n2_audio_params_route_simple_array_merge(int length,
195         unsigned char *array_src, unsigned char *array_dst)
196 {
197         int i;
198
199         if(length <= 0 || array_src == NULL || array_dst == NULL)
200                 return -1;
201
202         for(i=0 ; i < length ; i++) {
203                 if(array_dst[i] == 0)
204                         array_dst[i] = array_src[i];
205         }
206
207         return 0;
208 }
209
210 int yamaha_mc1n2_audio_params_route_path_array_merge(int length,
211         unsigned char *array_src, unsigned char *array_dst)
212 {
213         int i, j;
214         unsigned char v;
215
216         if(length <= 0 || array_src == NULL || array_dst == NULL)
217                 return -1;
218
219         for(i=0 ; i < length ; i++) {
220                 if(array_dst[i] == 0) {
221                         array_dst[i] = array_src[i];
222                 } else {
223                         v = array_src[i];
224
225                         for(j=0; j < 8 ; j++) {
226                                 if((1 << j) & array_dst[i]) {
227                                         if(j % 2 == 0)
228                                                 v &= ~(1 << (j+1));
229                                         else
230                                                 v &= ~(1 << (j-1));
231
232                                         v |= (1 << j);
233                                 }
234                         }
235
236                         array_dst[i] = v;
237                 }
238         }
239
240         return 0;
241 }
242
243 int yamaha_mc1n2_audio_params_route_merge(
244         struct yamaha_mc1n2_audio_params_route *params_src,
245         struct yamaha_mc1n2_audio_params_route *params_dst)
246 {
247         if(params_src == NULL || params_dst == NULL)
248                 return -1;
249
250         // ae_info
251         yamaha_mc1n2_audio_params_route_simple_array_merge(sizeof(params_src->ae_info.bOnOff),
252                 &params_src->ae_info.bOnOff, &params_dst->ae_info.bOnOff);
253         yamaha_mc1n2_audio_params_route_simple_array_merge(sizeof(params_src->ae_info.abBex),
254                 params_src->ae_info.abBex, params_dst->ae_info.abBex);
255         yamaha_mc1n2_audio_params_route_simple_array_merge(sizeof(params_src->ae_info.abWide),
256                 params_src->ae_info.abWide, params_dst->ae_info.abWide);
257         yamaha_mc1n2_audio_params_route_simple_array_merge(sizeof(params_src->ae_info.abDrc),
258                 params_src->ae_info.abDrc, params_dst->ae_info.abDrc);
259         yamaha_mc1n2_audio_params_route_simple_array_merge(sizeof(params_src->ae_info.abEq5),
260                 params_src->ae_info.abEq5, params_dst->ae_info.abEq5);
261         yamaha_mc1n2_audio_params_route_simple_array_merge(sizeof(params_src->ae_info.abEq3),
262                 params_src->ae_info.abEq3, params_dst->ae_info.abEq3);
263
264         // path_info
265         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asHpOut[0].abSrcOnOff),
266                 params_src->path_info.asHpOut[0].abSrcOnOff, params_dst->path_info.asHpOut[0].abSrcOnOff);
267         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asHpOut[1].abSrcOnOff),
268                 params_src->path_info.asHpOut[1].abSrcOnOff, params_dst->path_info.asHpOut[1].abSrcOnOff);
269         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asSpOut[0].abSrcOnOff),
270                 params_src->path_info.asSpOut[0].abSrcOnOff, params_dst->path_info.asSpOut[0].abSrcOnOff);
271         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asSpOut[1].abSrcOnOff),
272                 params_src->path_info.asSpOut[1].abSrcOnOff, params_dst->path_info.asSpOut[1].abSrcOnOff);
273         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asRcOut[0].abSrcOnOff),
274                 params_src->path_info.asRcOut[0].abSrcOnOff, params_dst->path_info.asRcOut[0].abSrcOnOff);
275         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asLout1[0].abSrcOnOff),
276                 params_src->path_info.asLout1[0].abSrcOnOff, params_dst->path_info.asLout1[0].abSrcOnOff);
277         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asLout1[1].abSrcOnOff),
278                 params_src->path_info.asLout1[1].abSrcOnOff, params_dst->path_info.asLout1[1].abSrcOnOff);
279         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asLout2[0].abSrcOnOff),
280                 params_src->path_info.asLout2[0].abSrcOnOff, params_dst->path_info.asLout2[0].abSrcOnOff);
281         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asLout2[1].abSrcOnOff),
282                 params_src->path_info.asLout2[1].abSrcOnOff, params_dst->path_info.asLout2[1].abSrcOnOff);
283         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asPeak[0].abSrcOnOff),
284                 params_src->path_info.asPeak[0].abSrcOnOff, params_dst->path_info.asPeak[0].abSrcOnOff);
285         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asDit0[0].abSrcOnOff),
286                 params_src->path_info.asDit0[0].abSrcOnOff, params_dst->path_info.asDit0[0].abSrcOnOff);
287         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asDit1[0].abSrcOnOff),
288                 params_src->path_info.asDit1[0].abSrcOnOff, params_dst->path_info.asDit1[0].abSrcOnOff);
289         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asDit2[0].abSrcOnOff),
290                 params_src->path_info.asDit2[0].abSrcOnOff, params_dst->path_info.asDit2[0].abSrcOnOff);
291         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asDac[0].abSrcOnOff),
292                 params_src->path_info.asDac[0].abSrcOnOff, params_dst->path_info.asDac[0].abSrcOnOff);
293         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asDac[1].abSrcOnOff),
294                 params_src->path_info.asDac[1].abSrcOnOff, params_dst->path_info.asDac[1].abSrcOnOff);
295         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asAe[0].abSrcOnOff),
296                 params_src->path_info.asAe[0].abSrcOnOff, params_dst->path_info.asAe[0].abSrcOnOff);
297         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asCdsp[0].abSrcOnOff),
298                 params_src->path_info.asCdsp[0].abSrcOnOff, params_dst->path_info.asCdsp[0].abSrcOnOff);
299         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asCdsp[1].abSrcOnOff),
300                 params_src->path_info.asCdsp[1].abSrcOnOff, params_dst->path_info.asCdsp[1].abSrcOnOff);
301         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asCdsp[2].abSrcOnOff),
302                 params_src->path_info.asCdsp[2].abSrcOnOff, params_dst->path_info.asCdsp[2].abSrcOnOff);
303         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asCdsp[3].abSrcOnOff),
304                 params_src->path_info.asCdsp[3].abSrcOnOff, params_dst->path_info.asCdsp[3].abSrcOnOff);
305         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asAdc0[0].abSrcOnOff),
306                 params_src->path_info.asAdc0[0].abSrcOnOff, params_dst->path_info.asAdc0[0].abSrcOnOff);
307         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asAdc0[1].abSrcOnOff),
308                 params_src->path_info.asAdc0[1].abSrcOnOff, params_dst->path_info.asAdc0[1].abSrcOnOff);
309         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asAdc1[0].abSrcOnOff),
310                 params_src->path_info.asAdc1[0].abSrcOnOff, params_dst->path_info.asAdc1[0].abSrcOnOff);
311         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asMix[0].abSrcOnOff),
312                 params_src->path_info.asMix[0].abSrcOnOff, params_dst->path_info.asMix[0].abSrcOnOff);
313         yamaha_mc1n2_audio_params_route_path_array_merge(sizeof(params_src->path_info.asBias[0].abSrcOnOff),
314                 params_src->path_info.asBias[0].abSrcOnOff, params_dst->path_info.asBias[0].abSrcOnOff);
315
316         // dac_info
317         yamaha_mc1n2_audio_params_route_simple_array_merge(sizeof(params_src->dac_info.bMasterSwap),
318                 &params_src->dac_info.bMasterSwap, &params_dst->dac_info.bMasterSwap);
319         yamaha_mc1n2_audio_params_route_simple_array_merge(sizeof(params_src->dac_info.bVoiceSwap),
320                 &params_src->dac_info.bVoiceSwap, &params_dst->dac_info.bVoiceSwap);
321         yamaha_mc1n2_audio_params_route_simple_array_merge(sizeof(params_src->dac_info.bDcCut),
322                 &params_src->dac_info.bDcCut, &params_dst->dac_info.bDcCut);
323
324         return 0;
325 }
326
327 int yamaha_mc1n2_audio_route_start(struct yamaha_mc1n2_audio_pdata *pdata)
328 {
329         struct yamaha_mc1n2_audio_params_route *params_route = NULL;
330         struct yamaha_mc1n2_audio_params_init *params_init = NULL;
331         struct yamaha_mc1n2_audio_params_route *params = NULL;
332         struct yamaha_mc1n2_audio_params_route params_src;
333         struct yamaha_mc1n2_audio_params_route params_dst;
334
335         int rc;
336
337         LOGD("%s()", __func__);
338
339         if(pdata == NULL || pdata->ops == NULL)
340                 return -1;
341
342         params_init = pdata->ops->params.init;
343         if(params_init == NULL)
344                 return -1;
345
346         // Copy the init params
347         memcpy(&params_src.ae_info, &params_init->ae_info, sizeof(params_src.ae_info));
348         memcpy(&params_src.path_info, &params_init->path_info, sizeof(params_src.path_info));
349         memcpy(&params_src.dac_info, &params_init->dac_info, sizeof(params_src.dac_info));
350
351 output_merge:
352         if(pdata->output_state) {
353                 params_route = yamaha_mc1n2_audio_params_route_find(pdata,
354                         pdata->output_device, YAMAHA_MC1N2_AUDIO_DIRECTION_OUTPUT);
355                 if(params_route == NULL)
356                         goto input_merge;
357
358                 memcpy(&params_dst, params_route, sizeof(params_dst));
359                 yamaha_mc1n2_audio_params_route_merge(&params_src, &params_dst);
360                 memcpy(&params_src, &params_dst, sizeof(params_src));
361         }
362
363 input_merge:
364         if(pdata->input_state) {
365                 params_route = yamaha_mc1n2_audio_params_route_find(pdata,
366                         pdata->input_device, YAMAHA_MC1N2_AUDIO_DIRECTION_INPUT);
367                 if(params_route == NULL)
368                         goto modem_merge;
369
370                 memcpy(&params_dst, params_route, sizeof(params_dst));
371                 yamaha_mc1n2_audio_params_route_merge(&params_src, &params_dst);
372                 memcpy(&params_src, &params_dst, sizeof(params_src));
373         }
374
375 modem_merge:
376         if(pdata->modem_state) {
377                 params_route = yamaha_mc1n2_audio_params_route_find(pdata,
378                         pdata->output_device, YAMAHA_MC1N2_AUDIO_DIRECTION_MODEM);
379                 if(params_route == NULL)
380                         goto route_start;
381
382                 memcpy(&params_dst, params_route, sizeof(params_dst));
383                 yamaha_mc1n2_audio_params_route_merge(&params_src, &params_dst);
384                 memcpy(&params_src, &params_dst, sizeof(params_src));
385         }
386
387 route_start:
388         params = &(params_src);
389
390         rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_AUDIOENGINE,
391                 &params->ae_info, 0x0f);
392         if(rc < 0) {
393                 LOGE("SET_AUDIOENGINE IOCTL failed, aborting!");
394                 return -1;
395         }
396
397         rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_PATH,
398                 &params->path_info, 0x00);
399         if(rc < 0) {
400                 LOGE("SET_PATH IOCTL failed, aborting!");
401                 return -1;
402         }
403
404         rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_DAC,
405                 &params->dac_info, 0x07);
406         if(rc < 0) {
407                 LOGE("SET_DAC IOCTL failed, aborting!");
408                 return -1;
409         }
410
411         return 0;
412 }
413
414 int yamaha_mc1n2_audio_output_start(struct yamaha_mc1n2_audio_pdata *pdata)
415 {
416         int rc;
417
418         LOGD("%s()", __func__);
419
420         if(pdata == NULL || pdata->ops == NULL)
421                 return -1;
422
423         pdata->output_state = 1;
424
425         rc = yamaha_mc1n2_audio_route_start(pdata);
426         if(rc < 0) {
427                 LOGE("Route start failed, aborting!");
428                 return -1;
429         }
430
431         rc = yamaha_mc1n2_audio_ioctl_notify(pdata, MCDRV_NOTIFY_MEDIA_PLAY_START);
432         if(rc < 0) {
433                 LOGE("NOTIFY_MEDIA_PLAY_START IOCTL failed, aborting!");
434                 return -1;
435         }
436
437         return 0;
438 }
439
440 int yamaha_mc1n2_audio_output_stop(struct yamaha_mc1n2_audio_pdata *pdata)
441 {
442         int rc;
443
444         LOGD("%s()", __func__);
445
446         if(pdata == NULL || pdata->ops == NULL)
447                 return -1;
448
449         pdata->output_state = 0;
450
451         rc = yamaha_mc1n2_audio_route_start(pdata);
452         if(rc < 0) {
453                 LOGE("Route start failed, aborting!");
454                 return -1;
455         }
456
457         rc = yamaha_mc1n2_audio_ioctl_notify(pdata, MCDRV_NOTIFY_MEDIA_PLAY_STOP);
458         if(rc < 0) {
459                 LOGE("NOTIFY_MEDIA_PLAY_STOP IOCTL failed, aborting!");
460                 return -1;
461         }
462
463         return 0;
464 }
465
466 int yamaha_mc1n2_audio_input_start(struct yamaha_mc1n2_audio_pdata *pdata)
467 {
468         int rc;
469
470         LOGD("%s()", __func__);
471
472         if(pdata == NULL || pdata->ops == NULL)
473                 return -1;
474
475         pdata->input_state = 1;
476
477         rc = yamaha_mc1n2_audio_route_start(pdata);
478         if(rc < 0) {
479                 LOGE("Route start failed, aborting!");
480                 return -1;
481         }
482
483         rc = yamaha_mc1n2_audio_ioctl_notify(pdata, MCDRV_NOTIFY_VOICE_REC_START);
484         if(rc < 0) {
485                 LOGE("NOTIFY_VOICE_REC_START IOCTL failed, aborting!");
486                 return -1;
487         }
488
489         return 0;
490 }
491
492 int yamaha_mc1n2_audio_input_stop(struct yamaha_mc1n2_audio_pdata *pdata)
493 {
494         int rc;
495
496         LOGD("%s()", __func__);
497
498         if(pdata == NULL || pdata->ops == NULL)
499                 return -1;
500
501         pdata->input_state = 0;
502
503         rc = yamaha_mc1n2_audio_route_start(pdata);
504         if(rc < 0) {
505                 LOGE("Route start failed, aborting!");
506                 return -1;
507         }
508
509         rc = yamaha_mc1n2_audio_ioctl_notify(pdata, MCDRV_NOTIFY_VOICE_REC_STOP);
510         if(rc < 0) {
511                 LOGE("NOTIFY_VOICE_REC_START IOCTL failed, aborting!");
512                 return -1;
513         }
514
515         return 0;
516 }
517
518 int yamaha_mc1n2_audio_modem_start(struct yamaha_mc1n2_audio_pdata *pdata)
519 {
520         int rc;
521
522         LOGD("%s()", __func__);
523
524         if(pdata == NULL || pdata->ops == NULL)
525                 return -1;
526
527         pdata->modem_state = 1;
528
529         rc = yamaha_mc1n2_audio_route_start(pdata);
530         if(rc < 0) {
531                 LOGE("Route start failed, aborting!");
532                 return -1;
533         }
534
535         rc = yamaha_mc1n2_audio_ioctl_notify(pdata, MCDRV_NOTIFY_CALL_START);
536         if(rc < 0) {
537                 LOGE("NOTIFY_CALL_START IOCTL failed, aborting!");
538                 return -1;
539         }
540
541         return 0;
542 }
543
544 int yamaha_mc1n2_audio_modem_stop(struct yamaha_mc1n2_audio_pdata *pdata)
545 {
546         int rc;
547
548         LOGD("%s()", __func__);
549
550         if(pdata == NULL || pdata->ops == NULL)
551                 return -1;
552
553         pdata->modem_state = 0;
554
555         rc = yamaha_mc1n2_audio_route_start(pdata);
556         if(rc < 0) {
557                 LOGE("Route start failed, aborting!");
558                 return -1;
559         }
560
561         rc = yamaha_mc1n2_audio_ioctl_notify(pdata, MCDRV_NOTIFY_CALL_STOP);
562         if(rc < 0) {
563                 LOGE("NOTIFY_CALL_START IOCTL failed, aborting!");
564                 return -1;
565         }
566
567         return 0;
568 }
569
570 /*
571  * Values configuration
572  */
573
574 int yamaha_mc1n2_audio_set_route(struct yamaha_mc1n2_audio_pdata *pdata,
575         audio_devices_t device)
576 {
577         int changed = 0;
578
579         LOGD("%s(%x)", __func__, device);
580
581         if(pdata == NULL)
582                 return -1;
583
584         if(audio_is_output_device(device) && pdata->output_device != device) {
585                 pdata->output_device = device;
586                 changed = 1;
587         } else if(audio_is_input_device(device) && pdata->input_device != device) {
588                 pdata->input_device = device;
589                 changed = 1;
590         }
591
592         if(changed && (pdata->output_state || pdata->input_state || pdata->modem_state))
593                 return yamaha_mc1n2_audio_route_start(pdata);
594
595         return 0;
596 }
597
598 char *yamaha_mc1n2_audio_get_hw_node(struct yamaha_mc1n2_audio_pdata *pdata)
599 {
600         if(pdata == NULL)
601                 return NULL;
602
603         return pdata->ops->hw_node;
604 }
605
606 /*
607  * Init/Deinit
608  */
609
610 struct yamaha_mc1n2_audio_pdata *yamaha_mc1n2_audio_platform_get(
611         char *device_name)
612 {
613         int i;
614
615         if(device_name == NULL)
616                 return NULL;
617
618         LOGD("Found %d registered platforms",
619                 yamaha_mc1n2_audio_platforms_count);
620
621         for(i=0 ; i < yamaha_mc1n2_audio_platforms_count ; i++) {
622                 if(yamaha_mc1n2_audio_platforms[i] != NULL &&
623                         yamaha_mc1n2_audio_platforms[i]->name != NULL) {
624                         if(strcmp(yamaha_mc1n2_audio_platforms[i]->name, device_name) == 0) {
625                                 return yamaha_mc1n2_audio_platforms[i];
626                         }
627                 }
628         }
629
630         return NULL;
631 }
632
633
634 int yamaha_mc1n2_audio_start(struct yamaha_mc1n2_audio_pdata **pdata_p,
635         char *device_name)
636 {
637         struct yamaha_mc1n2_audio_pdata *pdata = NULL;
638         int rc;
639
640         LOGD("%s(%s)", __func__, device_name);
641
642         if(pdata_p == NULL || device_name == NULL)
643                 return -1;
644
645         pdata = yamaha_mc1n2_audio_platform_get(device_name);
646         if(pdata == NULL) {
647                 LOGE("Unable to find requested platform: %s", device_name);
648                 return -1;
649         }
650
651         *pdata_p = pdata;
652
653         return 0;
654 }
655
656 int yamaha_mc1n2_audio_stop(struct yamaha_mc1n2_audio_pdata *pdata)
657 {
658         if(pdata == NULL)
659                 return -1;
660
661         LOGD("%s()", __func__);
662
663         return 0;
664 }