diff options
Diffstat (limited to 'target/linux/pxa/patches-2.6.21/027-ucb1400-ac97-audio.patch')
-rw-r--r-- | target/linux/pxa/patches-2.6.21/027-ucb1400-ac97-audio.patch | 294 |
1 files changed, 0 insertions, 294 deletions
diff --git a/target/linux/pxa/patches-2.6.21/027-ucb1400-ac97-audio.patch b/target/linux/pxa/patches-2.6.21/027-ucb1400-ac97-audio.patch deleted file mode 100644 index e1686da2ba..0000000000 --- a/target/linux/pxa/patches-2.6.21/027-ucb1400-ac97-audio.patch +++ /dev/null @@ -1,294 +0,0 @@ ---- a/sound/pci/ac97/ac97_codec.c -+++ b/sound/pci/ac97/ac97_codec.c -@@ -158,7 +158,7 @@ static const struct ac97_codec_id snd_ac - { 0x4e534300, 0xffffffff, "LM4540,43,45,46,48", NULL, NULL }, // only guess --jk - { 0x4e534331, 0xffffffff, "LM4549", NULL, NULL }, - { 0x4e534350, 0xffffffff, "LM4550", patch_lm4550, NULL }, // volume wrap fix --{ 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL }, -+{ 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL, AC97_HAS_NO_STD_PCM }, - { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, - { 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, - { 0x54524106, 0xffffffff, "TR28026", NULL, NULL }, ---- a/sound/pci/ac97/ac97_patch.c -+++ b/sound/pci/ac97/ac97_patch.c -@@ -29,6 +29,10 @@ - #include <linux/slab.h> - #include <linux/mutex.h> - -+#include <linux/proc_fs.h> -+#include <linux/string.h> -+#include <linux/ctype.h> -+ - #include <sound/core.h> - #include <sound/pcm.h> - #include <sound/control.h> -@@ -406,6 +410,227 @@ int patch_yamaha_ymf753(struct snd_ac97 - } - - /* -+ * UCB1400 codec -+ */ -+ -+#define AC97_UCB1400_FCSR1 0x6a -+#define AC97_UCB1400_FCSR2 0x6c -+ -+static const struct snd_kcontrol_new ucb1400_snd_ac97_controls[] = { -+ AC97_SINGLE("Tone Control - Bass", AC97_UCB1400_FCSR1, 11, 4, 0), -+ AC97_SINGLE("Tone Control - Treble", AC97_UCB1400_FCSR1, 9, 2, 0), -+ AC97_SINGLE("Headphone Playback Switch", AC97_UCB1400_FCSR1, 6, 1, 0), -+ AC97_SINGLE("De-emphasis", AC97_UCB1400_FCSR1, 5, 1, 0), -+ AC97_SINGLE("DC Filter", AC97_UCB1400_FCSR1, 4, 1, 0), -+ AC97_SINGLE("Hi-pass Filter", AC97_UCB1400_FCSR1, 3, 1, 0), -+ AC97_SINGLE("ADC Filter", AC97_UCB1400_FCSR2, 12, 1, 0), -+}; -+ -+#define NUM_GPIO_LINES 10 -+ -+static struct proc_dir_entry *proc_gpio_parent; -+static struct proc_dir_entry *proc_gpios[NUM_GPIO_LINES]; -+ -+typedef struct -+{ -+ int gpio; -+ char name[32]; -+ struct snd_ac97 *ac97; -+} gpio_summary_type; -+ -+static gpio_summary_type gpio_summaries[NUM_GPIO_LINES] = -+{ -+ { 0, "UCB1400-0-0" }, -+ { 1, "UCB1400-0-1" }, -+ { 2, "UCB1400-0-2" }, -+ { 3, "UCB1400-0-3" }, -+ { 4, "UCB1400-0-4" }, -+ { 5, "UCB1400-0-5" }, -+ { 6, "UCB1400-0-6" }, -+ { 7, "UCB1400-0-7" }, -+ { 8, "UCB1400-0-8" }, -+ { 9, "UCB1400-0-9" } -+}; -+ -+ -+static int proc_ucb1400_ac97_gpio_write(struct file *file, const char __user *buf, -+ unsigned long count, void *data) -+{ -+ char *cur, lbuf[count + 1]; -+ gpio_summary_type *summary = data; -+ u32 direction_is_out, operation_is_set; -+ int i = summary->gpio; -+ u16 dir, value; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EACCES; -+ -+ memset(lbuf, 0, count + 1); -+ -+ if (copy_from_user(lbuf, buf, count)) -+ return -EFAULT; -+ -+ cur = lbuf; -+ -+ // Get current values -+ direction_is_out = !!(snd_ac97_read(summary->ac97, 0x5c) & (0x0001 << i)); -+ operation_is_set = !!(snd_ac97_read(summary->ac97, 0x5a) & (0x0001 << i)); -+ while(1) -+ { -+ // We accept options: {GPIO|AF1|AF2|AF3}, {set|clear}, {in|out} -+ // Anything else is an error -+ while(cur[0] && (isspace(cur[0]) || ispunct(cur[0]))) cur = &(cur[1]); -+ -+ if('\0' == cur[0]) break; -+ -+ // Ok, so now we're pointing at the start of something -+ switch(cur[0]) -+ { -+ case 'G': -+ // Check that next is "PIO" -- '\0' will cause safe short-circuit if end of buf -+ if(!(cur[1] == 'P' && cur[2] == 'I' && cur[3] == 'O')) goto parse_error; -+ cur = &(cur[4]); -+ break; -+ case 's': -+ if(!(cur[1] == 'e' && cur[2] == 't')) goto parse_error; -+ operation_is_set = 1; -+ cur = &(cur[3]); -+ break; -+ case 'c': -+ if(!(cur[1] == 'l' && cur[2] == 'e' && cur[3] == 'a' && cur[4] == 'r')) goto -+parse_error; -+ operation_is_set = 0; -+ cur = &(cur[5]); -+ break; -+ case 'i': -+ if(!(cur[1] == 'n')) goto parse_error; -+ direction_is_out = 0; -+ cur = &(cur[2]); -+ break; -+ case 'o': -+ if(!(cur[1] == 'u' && cur[2] == 't')) goto parse_error; -+ direction_is_out = 1; -+ cur = &(cur[3]); -+ break; -+ default: goto parse_error; -+ } -+ } -+ -+ // set/get value -+ dir = snd_ac97_read(summary->ac97, 0x5c); -+ value = snd_ac97_read(summary->ac97, 0x5a); -+ if (direction_is_out) -+ { -+ dir |= 0x0001 << i; -+ if (operation_is_set) -+ { -+ value |= 0x0001 << i; -+ } -+ else -+ { -+ value &= ~(0x0001 << i); -+ } -+ -+ snd_ac97_write(summary->ac97, 0x5c, dir); -+ snd_ac97_write(summary->ac97, 0x5a, value); -+ } -+ else // direction in -+ { -+ dir &= ~(0x0001 << i); -+ snd_ac97_write(summary->ac97, 0x5c, dir); -+ operation_is_set = snd_ac97_read(summary->ac97, 0x5a) & ~(0x0001 << i); -+ } -+ -+#ifdef CONFIG_PROC_GPIO_DEBUG -+ printk(KERN_INFO "Set (%s,%s,%s) via /proc/gpio/%s\n", -+ "GPIO", -+ direction_is_out ? "out" : "in", -+ operation_is_set ? "set" : "clear", -+ summary->name); -+#endif -+ -+ return count; -+ -+parse_error: -+ printk(KERN_CRIT "Parse error: Expect \"GPIO|[set|clear]|[in|out] ...\"\n"); -+ return -EINVAL; -+} -+ -+static int proc_ucb1400_ac97_gpio_read(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ char *p = page; -+ gpio_summary_type *summary = data; -+ int len, i; /*, af;*/ -+ i = summary->gpio; -+ -+ p += sprintf(p, "%d\t%s\t%s\t%s\n", i, -+ "GPIO", -+ (snd_ac97_read(summary->ac97, 0x5c) & (0x0001 << i)) ? "out" : "in", -+ (snd_ac97_read(summary->ac97, 0x5a) & (0x0001 << i)) ? "set" : "clear"); -+ -+ len = (p - page) - off; -+ -+ if(len < 0) -+ { -+ len = 0; -+ } -+ -+ *eof = (len <= count) ? 1 : 0; -+ *start = page + off; -+ -+ return len; -+} -+ -+int patch_ucb1400(struct snd_ac97 * ac97) -+{ -+ int err, i; -+ -+ proc_gpio_parent = proc_mkdir("gpio", NULL); -+ if(!proc_gpio_parent) return 0; -+ -+ for(i=0; i < NUM_GPIO_LINES; i++) -+ { -+ proc_gpios[i] = create_proc_entry(gpio_summaries[i].name, 0644, proc_gpio_parent); -+ if(proc_gpios[i]) -+ { -+ gpio_summaries[i].ac97 = ac97; -+ proc_gpios[i]->data = &gpio_summaries[i]; -+ proc_gpios[i]->read_proc = proc_ucb1400_ac97_gpio_read; -+ proc_gpios[i]->write_proc = proc_ucb1400_ac97_gpio_write; -+ } -+ } -+ -+ for(i = 0; i < ARRAY_SIZE(ucb1400_snd_ac97_controls); i++) { -+ if((err = snd_ctl_add(ac97->bus->card, snd_ac97_cnew(&ucb1400_snd_ac97_controls[i], ac97))) < 0) -+ return err; -+ } -+ -+ snd_ac97_write_cache(ac97, AC97_UCB1400_FCSR1, -+ (0 << 11) | // 0 base boost -+ (0 << 9) | // 0 treble boost -+ (0 << 7) | // Mode = flat -+ (1 << 6) | // Headphones enable -+ (0 << 5) | // De-emphasis disabled -+ (1 << 4) | // DC filter enabled -+ (1 << 3) | // Hi-pass filter enabled -+ (0 << 2) | // disable interrupt signalling via GPIO_INT -+ (1 << 0) // clear ADC overflow status if set -+ ); -+ -+ snd_ac97_write_cache(ac97, AC97_UCB1400_FCSR2, -+ (0 << 15) | // must be 0 -+ (0 << 13) | // must be 0 -+ (1 << 12) | // ADC filter enabled -+ (0 << 10) | // must be 0 -+ (0 << 4) | // Smart low power mode on neither Codec nor PLL -+ (0 << 0) // must be 0 -+ ); -+ -+ return 0; -+} -+ -+/* - * May 2, 2003 Liam Girdwood <liam.girdwood@wolfsonmicro.com> - * removed broken wolfson00 patch. - * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717. -@@ -3408,41 +3633,3 @@ int patch_lm4550(struct snd_ac97 *ac97) - ac97->res_table = lm4550_restbl; - return 0; - } -- --/* -- * UCB1400 codec (http://www.semiconductors.philips.com/acrobat_download/datasheets/UCB1400-02.pdf) -- */ --static const struct snd_kcontrol_new snd_ac97_controls_ucb1400[] = { --/* enable/disable headphone driver which allows direct connection to -- stereo headphone without the use of external DC blocking -- capacitors */ --AC97_SINGLE("Headphone Driver", 0x6a, 6, 1, 0), --/* Filter used to compensate the DC offset is added in the ADC to remove idle -- tones from the audio band. */ --AC97_SINGLE("DC Filter", 0x6a, 4, 1, 0), --/* Control smart-low-power mode feature. Allows automatic power down -- of unused blocks in the ADC analog front end and the PLL. */ --AC97_SINGLE("Smart Low Power Mode", 0x6c, 4, 3, 0), --}; -- --static int patch_ucb1400_specific(struct snd_ac97 * ac97) --{ -- int idx, err; -- for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_ucb1400); idx++) -- if ((err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_ucb1400[idx], ac97))) < 0) -- return err; -- return 0; --} -- --static struct snd_ac97_build_ops patch_ucb1400_ops = { -- .build_specific = patch_ucb1400_specific, --}; -- --int patch_ucb1400(struct snd_ac97 * ac97) --{ -- ac97->build_ops = &patch_ucb1400_ops; -- /* enable headphone driver and smart low power mode by default */ -- snd_ac97_write(ac97, 0x6a, 0x0050); -- snd_ac97_write(ac97, 0x6c, 0x0030); -- return 0; --} |