2 * Copyright (C) 2012 Paul Kocialkowski <contact@paulk.fr>
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.
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.
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/>.
22 #include <sys/types.h>
26 #include <linux/ioctl.h>
28 #define LOG_TAG "Yamaha-MC1N2-Audio"
29 #include <cutils/log.h>
31 #include <system/audio.h>
33 #include <yamaha-mc1n2-audio.h>
35 struct yamaha_mc1n2_audio_pdata *yamaha_mc1n2_audio_platforms[] = {
39 int yamaha_mc1n2_audio_platforms_count = sizeof(yamaha_mc1n2_audio_platforms) /
40 sizeof(struct yamaha_mc1n2_audio_pdata *);
46 int yamaha_mc1n2_audio_ioctl(struct yamaha_mc1n2_audio_pdata *pdata,
47 int command, struct mc1n2_ctrl_args *hw_ctrl)
56 hw_node = yamaha_mc1n2_audio_get_hw_node(pdata);
58 LOGE("%s: error, missing hw_node!", __func__);
62 hw_fd = open(hw_node, O_RDWR);
64 LOGE("%s: error, unable to open hw_node (fd is %d)!", __func__, hw_fd);
68 rc = ioctl(hw_fd, command, hw_ctrl);
70 LOGE("%s: error, ioctl on hw_node failed (rc is %d)!", __func__, rc);
79 int yamaha_mc1n2_audio_ioctl_set_ctrl(struct yamaha_mc1n2_audio_pdata *pdata,
80 unsigned long command, void *data, unsigned long update_info)
82 struct mc1n2_ctrl_args hw_ctrl;
87 memset(&hw_ctrl, 0, sizeof(hw_ctrl));
88 hw_ctrl.dCmd = command;
90 hw_ctrl.dPrm = update_info;
92 return yamaha_mc1n2_audio_ioctl(pdata, MC1N2_IOCTL_SET_CTRL, &hw_ctrl);
95 int yamaha_mc1n2_audio_ioctl_notify(struct yamaha_mc1n2_audio_pdata *pdata,
96 unsigned long command)
98 struct mc1n2_ctrl_args hw_ctrl;
103 memset(&hw_ctrl, 0, sizeof(hw_ctrl));
104 hw_ctrl.dCmd = command;
106 return yamaha_mc1n2_audio_ioctl(pdata, MC1N2_IOCTL_NOTIFY, &hw_ctrl);
113 int yamaha_mc1n2_audio_routine_init(struct yamaha_mc1n2_audio_pdata *pdata)
115 struct yamaha_mc1n2_audio_routine_init *routine = NULL;
118 if(pdata == NULL || pdata->ops == NULL)
121 routine = pdata->ops->routines.init;
125 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_DAC,
126 &routine->dac_info, 0x07);
128 LOGE("SET_DAC IOCTL failed, aborting!");
132 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_ADC,
133 &routine->adc_info, 0x07);
135 LOGE("SET_ADC IOCTL failed, aborting!");
139 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_SP,
140 &routine->sp_info, 0x00);
142 LOGE("SET_SP IOCTL failed, aborting!");
146 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_PDM,
147 &routine->pdm_info, 0x7f);
149 LOGE("SET_PDM IOCTL failed, aborting!");
153 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_DNG,
154 &routine->dng_info, 0x3f3f3f);
156 LOGE("SET_DNG IOCTL failed, aborting!");
160 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_SYSEQ,
161 &routine->syseq_info, 0x03);
163 LOGE("SET_SYSEQ IOCTL failed, aborting!");
170 int yamaha_mc1n2_audio_routine_postopen(struct yamaha_mc1n2_audio_pdata *pdata)
172 struct yamaha_mc1n2_audio_routine_postopen *routine = NULL;
175 if(pdata == NULL || pdata->ops == NULL)
178 routine = pdata->ops->routines.postopen;
182 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_AUDIOENGINE,
183 &routine->ae_info, 0x0f);
185 LOGE("SET_AUDIOENGINE IOCTL failed, aborting!");
189 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_AUDIOENGINE,
190 &routine->ae_info, 0x0f);
192 LOGE("SET_AUDIOENGINE IOCTL failed, aborting!");
199 int yamaha_mc1n2_audio_routine_route_init(struct yamaha_mc1n2_audio_pdata *pdata)
201 struct yamaha_mc1n2_audio_routine_route *routine = NULL;
204 if(pdata == NULL || pdata->ops == NULL)
207 routine = pdata->ops->routines.route_init;
211 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_PATH,
212 &routine->path_info, 0x00);
214 LOGE("SET_PATH IOCTL failed, aborting!");
218 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_DAC,
219 &routine->dac_info, 0x07);
221 LOGE("SET_DAC IOCTL failed, aborting!");
228 int yamaha_mc1n2_audio_routine_route_start(struct yamaha_mc1n2_audio_pdata *pdata)
230 struct yamaha_mc1n2_audio_routine_route *routine = NULL;
234 if(pdata == NULL || pdata->ops == NULL || pdata->ops->routines.route_start == NULL)
237 for(i=0 ; i < pdata->ops->routines.route_start_count ; i++) {
238 if(pdata->ops->routines.route_start[i].device == pdata->device_current &&
239 pdata->ops->routines.route_start[i].mode == pdata->mode_current) {
240 routine = &(pdata->ops->routines.route_start[i]);
245 if(routine == NULL) {
246 LOGE("Unable to find route routine for device: 0x%x",
247 pdata->device_current);
251 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_AUDIOENGINE,
252 &routine->ae_info, 0x0f);
254 LOGE("SET_AUDIOENGINE IOCTL failed, aborting!");
258 rc = yamaha_mc1n2_audio_ioctl_notify(pdata, MCDRV_NOTIFY_MEDIA_PLAY_START);
260 LOGE("NOTIFY_MEDIA_PLAY_START IOCTL failed, aborting!");
264 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_PATH,
265 &routine->path_info, 0x00);
267 LOGE("SET_PATH IOCTL failed, aborting!");
271 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_DAC,
272 &routine->dac_info, 0x07);
274 LOGE("SET_DAC IOCTL failed, aborting!");
278 pdata->route_started = 1;
283 int yamaha_mc1n2_audio_routine_route_stop(struct yamaha_mc1n2_audio_pdata *pdata)
285 struct yamaha_mc1n2_audio_routine_route *routine = NULL;
288 if(pdata == NULL || pdata->ops == NULL)
291 routine = pdata->ops->routines.route_stop;
295 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_AUDIOENGINE,
296 &routine->ae_info, 0x0f);
298 LOGE("SET_AUDIOENGINE IOCTL failed, aborting!");
302 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_PATH,
303 &routine->path_info, 0x00);
305 LOGE("SET_PATH IOCTL failed, aborting!");
309 rc = yamaha_mc1n2_audio_ioctl_set_ctrl(pdata, MCDRV_SET_DAC,
310 &routine->dac_info, 0x07);
312 LOGE("SET_DAC IOCTL failed, aborting!");
316 pdata->route_started = 0;
322 * Values configuration
325 int yamaha_mc1n2_audio_set_route(struct yamaha_mc1n2_audio_pdata *pdata,
326 audio_devices_t device, audio_mode_t mode)
333 // In this case, we are making sound, so we need to switch now
334 if((pdata->device_current != device || pdata->mode_current != mode) &&
335 pdata->route_started) {
336 pdata->device_current = device;
337 pdata->mode_current = mode;
339 rc = yamaha_mc1n2_audio_routine_route_start(pdata);
343 pdata->device_current = device;
344 pdata->mode_current = mode;
349 char *yamaha_mc1n2_audio_get_hw_node(struct yamaha_mc1n2_audio_pdata *pdata)
354 return pdata->ops->hw_node;
361 struct yamaha_mc1n2_audio_pdata *yamaha_mc1n2_audio_platform_get(
366 if(device_name == NULL)
369 LOGD("Found %d registered platforms",
370 yamaha_mc1n2_audio_platforms_count);
372 for(i=0 ; i < yamaha_mc1n2_audio_platforms_count ; i++) {
373 if(yamaha_mc1n2_audio_platforms[i] != NULL &&
374 yamaha_mc1n2_audio_platforms[i]->name != NULL) {
375 if(strcmp(yamaha_mc1n2_audio_platforms[i]->name, device_name) == 0) {
376 return yamaha_mc1n2_audio_platforms[i];
385 int yamaha_mc1n2_audio_start(struct yamaha_mc1n2_audio_pdata **pdata_p,
388 struct yamaha_mc1n2_audio_pdata *pdata = NULL;
391 if(pdata_p == NULL || device_name == NULL)
394 pdata = yamaha_mc1n2_audio_platform_get(device_name);
396 LOGE("Unable to find requested platform: %s", device_name);
405 int yamaha_mc1n2_audio_stop(struct yamaha_mc1n2_audio_pdata *pdata)