/* * Audio support for HTC Magician * It uses PXA2xx i2Sound and UDA1380 modules * * Copyright (c) 2006 Philipp Zabel * * Based on: h2200_audio.c * Copyright (c) 2005 Giorgio Padrin giorgio@mandarinlogiq.org * Copyright (c) 2004,2005 Matthew Reimer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "pxa2xx-i2sound.h" #include extern struct platform_device blueangel_asic3; static struct snd_uda1380 uda; static void snd_htcblueangel_audio_set_codec_power(int mode) { /* SET_HTCBLUEANGEL_GPIO(CODEC_ON, mode); */ } static void snd_htcblueangel_audio_set_codec_reset(int mode) { /* SET_HTCBLUEANGEL_GPIO(CODEC_RESET, mode); */ } static void snd_htcblueangel_audio_set_mic_power(int mode) { asic3_set_gpio_out_a(&blueangel_asic3.dev, GPIOA_MIC_PWR_ON, mode ? 1 << GPIOA_MIC_PWR_ON : 0); } static void snd_htcblueangel_audio_set_speaker_power(int mode) { asic3_set_gpio_out_b(&blueangel_asic3.dev, GPIOB_SPK_PWR_ON, mode ? 1 << GPIOB_SPK_PWR_ON : 0); } static void snd_htcmagicican_audio_set_codec_reset(int mode) { if (mode) { // SET_HTCBLUEANGEL_GPIO(SPEAKER_ON, 1); // SET_HTCBLUEANGEL_GPIO(TDA_MODE, 0); /* Unmute the amplifier. */ } else { // SET_HTCBLUEANGEL_GPIO(TDA_MODE, 1); // SET_HTCBLUEANGEL_GPIO(SPEAKER_ON, 0); /* Mute the amplifier. */ } } static inline int snd_htcblueangel_audio_hp_detect(void) { //return GET_HTCBLUEANGEL_GPIO(HEADPHONE_IN) ? 1 : 0; return 0; } static irqreturn_t snd_htcblueangel_audio_hp_isr(int isr, void *data, struct pt_regs *regs) { snd_uda1380_hp_detected(&uda, snd_htcblueangel_audio_hp_detect()); return IRQ_HANDLED; } static void snd_htcblueangel_audio_hp_detection_on(void) { unsigned long flags; /* set_irq_type(IRQ_GPIO(GPIO_NR_HTCBLUEANGEL_HEADPHONE_IN), IRQT_BOTHEDGE); request_irq(IRQ_GPIO(GPIO_NR_HTCBLUEANGEL_HEADPHONE_IN), snd_htcblueangel_audio_hp_isr, SA_INTERRUPT | SA_SAMPLE_RANDOM, "earphone jack", NULL); local_irq_save(flags); snd_uda1380_hp_detected(&uda, snd_htcblueangel_audio_hp_detect()); local_irq_restore(flags); */ } static void snd_htcblueangel_audio_hp_detection_off(void) { //free_irq(IRQ_GPIO(GPIO_NR_HTCBLUEANGEL_HEADPHONE_IN), NULL); } static struct snd_uda1380 uda = { .line_in_connected = 0, .mic_connected = 1, .hp_or_line_out = 1, .capture_source = SND_UDA1380_CAP_SOURCE_MIC, .power_on_chip = snd_htcblueangel_audio_set_codec_power, .reset_pin = snd_htcblueangel_audio_set_codec_reset, .line_out_on = snd_htcblueangel_audio_set_speaker_power, .mic_on = snd_htcblueangel_audio_set_mic_power }; static int snd_htcblueangel_audio_activate(void) { /* UDA1380 at address 0x18 on PXA2xx I2C bus */ uda.i2c_client.adapter = i2c_get_adapter(0); uda.i2c_client.addr = 0x18; if (snd_uda1380_activate(&uda) == 0) { snd_htcblueangel_audio_hp_detection_on(); return 0; } else return -1; } static void snd_htcblueangel_audio_deactivate(void) { snd_htcblueangel_audio_hp_detection_off(); snd_uda1380_deactivate(&uda); } static int snd_htcblueangel_audio_open_stream(int stream) { return snd_uda1380_open_stream(&uda, stream); } static void snd_htcblueangel_audio_close_stream(int stream) { snd_uda1380_close_stream(&uda, stream); } static int snd_htcblueangel_audio_add_mixer_controls(struct snd_card *acard) { return snd_uda1380_add_mixer_controls(&uda, acard); } #ifdef CONFIG_PM static int snd_htcblueangel_audio_suspend(pm_message_t state) { snd_htcblueangel_audio_hp_detection_off(); snd_uda1380_suspend(&uda, state); return 0; } static int snd_htcblueangel_audio_resume(void) { snd_uda1380_resume(&uda); snd_htcblueangel_audio_hp_detection_on(); return 0; } #endif static struct snd_pxa2xx_i2sound_board htcblueangel_audio = { .name = "magician Audio", .desc = "HTC Blueangel Audio [codec Philips UDA1380]", .acard_id = "Blueangel Audio", .info = SND_PXA2xx_I2SOUND_INFO_CLOCK_FROM_PXA | SND_PXA2xx_I2SOUND_INFO_CAN_CAPTURE, .activate = snd_htcblueangel_audio_activate, .deactivate = snd_htcblueangel_audio_deactivate, .open_stream = snd_htcblueangel_audio_open_stream, .close_stream = snd_htcblueangel_audio_close_stream, .add_mixer_controls = snd_htcblueangel_audio_add_mixer_controls, #ifdef CONFIG_PM .suspend = snd_htcblueangel_audio_suspend, .resume = snd_htcblueangel_audio_resume #endif }; static int __init snd_htcblueangel_audio_init(void) { /* check machine */ if (!machine_is_blueangel()) { snd_printk(KERN_INFO "Module snd-htcblueangel_audio: not an HTC Blueangel!\n"); return -1; } request_module("i2c-pxa"); return snd_pxa2xx_i2sound_card_activate(&htcblueangel_audio); } static void __exit snd_htcblueangel_audio_exit(void) { snd_pxa2xx_i2sound_card_deactivate(); } module_init(snd_htcblueangel_audio_init); module_exit(snd_htcblueangel_audio_exit); MODULE_AUTHOR("Philipp Zabel, Giorgio Padrin, Matthew Reimer"); MODULE_DESCRIPTION("Audio support for HTC Blueangel"); MODULE_LICENSE("GPL");