rendered paste body/* * 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 <linux/module.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/platform_device.h>#include <asm/hardware.h>#include <linux/pm.h>#include <asm/mach-types.h>#include <asm/arch/pxa-regs.h>#include <asm/arch/htcblueangel-gpio.h>#include <asm/arch/htcblueangel-asic.h>#include "pxa2xx-i2sound.h"#include <sound/uda1380.h>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_PMstatic 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;}#endifstatic 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");