Loading arch/powerpc/include/asm/mpc52xx.h +1 −0 Original line number Diff line number Diff line Loading @@ -271,6 +271,7 @@ struct mpc52xx_intr { /* mpc52xx_common.c */ extern void mpc5200_setup_xlb_arbiter(void); extern void mpc52xx_declare_of_platform_devices(void); extern int mpc5200_psc_ac97_gpio_reset(int psc_number); extern void mpc52xx_map_common_devices(void); extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv); extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node); Loading arch/powerpc/include/asm/mpc52xx_psc.h +1 −0 Original line number Diff line number Diff line Loading @@ -131,6 +131,7 @@ #define MPC52xx_PSC_SICR_SIM_FIR (0x6 << 24) #define MPC52xx_PSC_SICR_SIM_CODEC_24 (0x7 << 24) #define MPC52xx_PSC_SICR_SIM_CODEC_32 (0xf << 24) #define MPC52xx_PSC_SICR_ACRB (0x8 << 24) #define MPC52xx_PSC_SICR_AWR (1 << 30) #define MPC52xx_PSC_SICR_GENCLK (1 << 23) #define MPC52xx_PSC_SICR_I2S (1 << 22) Loading arch/powerpc/kernel/setup-common.c +2 −0 Original line number Diff line number Diff line Loading @@ -96,7 +96,9 @@ struct screen_info screen_info = { /* Variables required to store legacy IO irq routing */ int of_i8042_kbd_irq; EXPORT_SYMBOL_GPL(of_i8042_kbd_irq); int of_i8042_aux_irq; EXPORT_SYMBOL_GPL(of_i8042_aux_irq); #ifdef __DO_IRQ_CANON /* XXX should go elsewhere eventually */ Loading arch/powerpc/platforms/52xx/mpc52xx_common.c +106 −0 Original line number Diff line number Diff line Loading @@ -12,9 +12,11 @@ #undef DEBUG #include <linux/gpio.h> #include <linux/kernel.h> #include <linux/spinlock.h> #include <linux/of_platform.h> #include <linux/of_gpio.h> #include <asm/io.h> #include <asm/prom.h> #include <asm/mpc52xx.h> Loading Loading @@ -82,6 +84,14 @@ mpc5200_setup_xlb_arbiter(void) iounmap(xlb); } /* * This variable is mapped in mpc52xx_map_common_devices and * used in mpc5200_psc_ac97_gpio_reset(). */ static DEFINE_SPINLOCK(gpio_lock); struct mpc52xx_gpio __iomem *simple_gpio; struct mpc52xx_gpio_wkup __iomem *wkup_gpio; /** * mpc52xx_declare_of_platform_devices: register internal devices and children * of the localplus bus to the of_platform Loading Loading @@ -109,6 +119,15 @@ static struct of_device_id mpc52xx_cdm_ids[] __initdata = { { .compatible = "mpc5200-cdm", }, /* old */ {} }; static const struct of_device_id mpc52xx_gpio_simple[] = { { .compatible = "fsl,mpc5200-gpio", }, {} }; static const struct of_device_id mpc52xx_gpio_wkup[] = { { .compatible = "fsl,mpc5200-gpio-wkup", }, {} }; /** * mpc52xx_map_common_devices: iomap devices required by common code Loading @@ -135,6 +154,16 @@ mpc52xx_map_common_devices(void) np = of_find_matching_node(NULL, mpc52xx_cdm_ids); mpc52xx_cdm = of_iomap(np, 0); of_node_put(np); /* simple_gpio registers */ np = of_find_matching_node(NULL, mpc52xx_gpio_simple); simple_gpio = of_iomap(np, 0); of_node_put(np); /* wkup_gpio registers */ np = of_find_matching_node(NULL, mpc52xx_gpio_wkup); wkup_gpio = of_iomap(np, 0); of_node_put(np); } /** Loading Loading @@ -233,3 +262,80 @@ mpc52xx_restart(char *cmd) while (1); } #define PSC1_RESET 0x1 #define PSC1_SYNC 0x4 #define PSC1_SDATA_OUT 0x1 #define PSC2_RESET 0x2 #define PSC2_SYNC (0x4<<4) #define PSC2_SDATA_OUT (0x1<<4) #define MPC52xx_GPIO_PSC1_MASK 0x7 #define MPC52xx_GPIO_PSC2_MASK (0x7<<4) /** * mpc5200_psc_ac97_gpio_reset: Use gpio pins to reset the ac97 bus * * @psc: psc number to reset (only psc 1 and 2 support ac97) */ int mpc5200_psc_ac97_gpio_reset(int psc_number) { unsigned long flags; u32 gpio; u32 mux; int out; int reset; int sync; if ((!simple_gpio) || (!wkup_gpio)) return -ENODEV; switch (psc_number) { case 0: reset = PSC1_RESET; /* AC97_1_RES */ sync = PSC1_SYNC; /* AC97_1_SYNC */ out = PSC1_SDATA_OUT; /* AC97_1_SDATA_OUT */ gpio = MPC52xx_GPIO_PSC1_MASK; break; case 1: reset = PSC2_RESET; /* AC97_2_RES */ sync = PSC2_SYNC; /* AC97_2_SYNC */ out = PSC2_SDATA_OUT; /* AC97_2_SDATA_OUT */ gpio = MPC52xx_GPIO_PSC2_MASK; break; default: pr_err(__FILE__ ": Unable to determine PSC, no ac97 " "cold-reset will be performed\n"); return -ENODEV; } spin_lock_irqsave(&gpio_lock, flags); /* Reconfiure pin-muxing to gpio */ mux = in_be32(&simple_gpio->port_config); out_be32(&simple_gpio->port_config, mux & (~gpio)); /* enable gpio pins for output */ setbits8(&wkup_gpio->wkup_gpioe, reset); setbits32(&simple_gpio->simple_gpioe, sync | out); setbits8(&wkup_gpio->wkup_ddr, reset); setbits32(&simple_gpio->simple_ddr, sync | out); /* Assert cold reset */ clrbits32(&simple_gpio->simple_dvo, sync | out); clrbits8(&wkup_gpio->wkup_dvo, reset); /* wait at lease 1 us */ udelay(2); /* Deassert reset */ setbits8(&wkup_gpio->wkup_dvo, reset); /* Restore pin-muxing */ out_be32(&simple_gpio->port_config, mux); spin_unlock_irqrestore(&gpio_lock, flags); return 0; } EXPORT_SYMBOL(mpc5200_psc_ac97_gpio_reset); sound/soc/fsl/mpc5200_psc_ac97.c +18 −4 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <asm/time.h> #include <asm/delay.h> #include <asm/mpc52xx.h> #include <asm/mpc52xx_psc.h> #include "mpc5200_dma.h" Loading Loading @@ -100,19 +101,32 @@ static void psc_ac97_warm_reset(struct snd_ac97 *ac97) { struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; mutex_lock(&psc_dma->mutex); out_be32(®s->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_AWR); udelay(3); out_be32(®s->sicr, psc_dma->sicr); mutex_unlock(&psc_dma->mutex); } static void psc_ac97_cold_reset(struct snd_ac97 *ac97) { struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; /* Do a cold reset */ out_8(®s->op1, MPC52xx_PSC_OP_RES); udelay(10); out_8(®s->op0, MPC52xx_PSC_OP_RES); mutex_lock(&psc_dma->mutex); dev_dbg(psc_dma->dev, "cold reset\n"); mpc5200_psc_ac97_gpio_reset(psc_dma->id); /* Notify the PSC that a reset has occurred */ out_be32(®s->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_ACRB); /* Re-enable RX and TX */ out_8(®s->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE); mutex_unlock(&psc_dma->mutex); msleep(1); psc_ac97_warm_reset(ac97); } Loading Loading
arch/powerpc/include/asm/mpc52xx.h +1 −0 Original line number Diff line number Diff line Loading @@ -271,6 +271,7 @@ struct mpc52xx_intr { /* mpc52xx_common.c */ extern void mpc5200_setup_xlb_arbiter(void); extern void mpc52xx_declare_of_platform_devices(void); extern int mpc5200_psc_ac97_gpio_reset(int psc_number); extern void mpc52xx_map_common_devices(void); extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv); extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node); Loading
arch/powerpc/include/asm/mpc52xx_psc.h +1 −0 Original line number Diff line number Diff line Loading @@ -131,6 +131,7 @@ #define MPC52xx_PSC_SICR_SIM_FIR (0x6 << 24) #define MPC52xx_PSC_SICR_SIM_CODEC_24 (0x7 << 24) #define MPC52xx_PSC_SICR_SIM_CODEC_32 (0xf << 24) #define MPC52xx_PSC_SICR_ACRB (0x8 << 24) #define MPC52xx_PSC_SICR_AWR (1 << 30) #define MPC52xx_PSC_SICR_GENCLK (1 << 23) #define MPC52xx_PSC_SICR_I2S (1 << 22) Loading
arch/powerpc/kernel/setup-common.c +2 −0 Original line number Diff line number Diff line Loading @@ -96,7 +96,9 @@ struct screen_info screen_info = { /* Variables required to store legacy IO irq routing */ int of_i8042_kbd_irq; EXPORT_SYMBOL_GPL(of_i8042_kbd_irq); int of_i8042_aux_irq; EXPORT_SYMBOL_GPL(of_i8042_aux_irq); #ifdef __DO_IRQ_CANON /* XXX should go elsewhere eventually */ Loading
arch/powerpc/platforms/52xx/mpc52xx_common.c +106 −0 Original line number Diff line number Diff line Loading @@ -12,9 +12,11 @@ #undef DEBUG #include <linux/gpio.h> #include <linux/kernel.h> #include <linux/spinlock.h> #include <linux/of_platform.h> #include <linux/of_gpio.h> #include <asm/io.h> #include <asm/prom.h> #include <asm/mpc52xx.h> Loading Loading @@ -82,6 +84,14 @@ mpc5200_setup_xlb_arbiter(void) iounmap(xlb); } /* * This variable is mapped in mpc52xx_map_common_devices and * used in mpc5200_psc_ac97_gpio_reset(). */ static DEFINE_SPINLOCK(gpio_lock); struct mpc52xx_gpio __iomem *simple_gpio; struct mpc52xx_gpio_wkup __iomem *wkup_gpio; /** * mpc52xx_declare_of_platform_devices: register internal devices and children * of the localplus bus to the of_platform Loading Loading @@ -109,6 +119,15 @@ static struct of_device_id mpc52xx_cdm_ids[] __initdata = { { .compatible = "mpc5200-cdm", }, /* old */ {} }; static const struct of_device_id mpc52xx_gpio_simple[] = { { .compatible = "fsl,mpc5200-gpio", }, {} }; static const struct of_device_id mpc52xx_gpio_wkup[] = { { .compatible = "fsl,mpc5200-gpio-wkup", }, {} }; /** * mpc52xx_map_common_devices: iomap devices required by common code Loading @@ -135,6 +154,16 @@ mpc52xx_map_common_devices(void) np = of_find_matching_node(NULL, mpc52xx_cdm_ids); mpc52xx_cdm = of_iomap(np, 0); of_node_put(np); /* simple_gpio registers */ np = of_find_matching_node(NULL, mpc52xx_gpio_simple); simple_gpio = of_iomap(np, 0); of_node_put(np); /* wkup_gpio registers */ np = of_find_matching_node(NULL, mpc52xx_gpio_wkup); wkup_gpio = of_iomap(np, 0); of_node_put(np); } /** Loading Loading @@ -233,3 +262,80 @@ mpc52xx_restart(char *cmd) while (1); } #define PSC1_RESET 0x1 #define PSC1_SYNC 0x4 #define PSC1_SDATA_OUT 0x1 #define PSC2_RESET 0x2 #define PSC2_SYNC (0x4<<4) #define PSC2_SDATA_OUT (0x1<<4) #define MPC52xx_GPIO_PSC1_MASK 0x7 #define MPC52xx_GPIO_PSC2_MASK (0x7<<4) /** * mpc5200_psc_ac97_gpio_reset: Use gpio pins to reset the ac97 bus * * @psc: psc number to reset (only psc 1 and 2 support ac97) */ int mpc5200_psc_ac97_gpio_reset(int psc_number) { unsigned long flags; u32 gpio; u32 mux; int out; int reset; int sync; if ((!simple_gpio) || (!wkup_gpio)) return -ENODEV; switch (psc_number) { case 0: reset = PSC1_RESET; /* AC97_1_RES */ sync = PSC1_SYNC; /* AC97_1_SYNC */ out = PSC1_SDATA_OUT; /* AC97_1_SDATA_OUT */ gpio = MPC52xx_GPIO_PSC1_MASK; break; case 1: reset = PSC2_RESET; /* AC97_2_RES */ sync = PSC2_SYNC; /* AC97_2_SYNC */ out = PSC2_SDATA_OUT; /* AC97_2_SDATA_OUT */ gpio = MPC52xx_GPIO_PSC2_MASK; break; default: pr_err(__FILE__ ": Unable to determine PSC, no ac97 " "cold-reset will be performed\n"); return -ENODEV; } spin_lock_irqsave(&gpio_lock, flags); /* Reconfiure pin-muxing to gpio */ mux = in_be32(&simple_gpio->port_config); out_be32(&simple_gpio->port_config, mux & (~gpio)); /* enable gpio pins for output */ setbits8(&wkup_gpio->wkup_gpioe, reset); setbits32(&simple_gpio->simple_gpioe, sync | out); setbits8(&wkup_gpio->wkup_ddr, reset); setbits32(&simple_gpio->simple_ddr, sync | out); /* Assert cold reset */ clrbits32(&simple_gpio->simple_dvo, sync | out); clrbits8(&wkup_gpio->wkup_dvo, reset); /* wait at lease 1 us */ udelay(2); /* Deassert reset */ setbits8(&wkup_gpio->wkup_dvo, reset); /* Restore pin-muxing */ out_be32(&simple_gpio->port_config, mux); spin_unlock_irqrestore(&gpio_lock, flags); return 0; } EXPORT_SYMBOL(mpc5200_psc_ac97_gpio_reset);
sound/soc/fsl/mpc5200_psc_ac97.c +18 −4 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <asm/time.h> #include <asm/delay.h> #include <asm/mpc52xx.h> #include <asm/mpc52xx_psc.h> #include "mpc5200_dma.h" Loading Loading @@ -100,19 +101,32 @@ static void psc_ac97_warm_reset(struct snd_ac97 *ac97) { struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; mutex_lock(&psc_dma->mutex); out_be32(®s->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_AWR); udelay(3); out_be32(®s->sicr, psc_dma->sicr); mutex_unlock(&psc_dma->mutex); } static void psc_ac97_cold_reset(struct snd_ac97 *ac97) { struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; /* Do a cold reset */ out_8(®s->op1, MPC52xx_PSC_OP_RES); udelay(10); out_8(®s->op0, MPC52xx_PSC_OP_RES); mutex_lock(&psc_dma->mutex); dev_dbg(psc_dma->dev, "cold reset\n"); mpc5200_psc_ac97_gpio_reset(psc_dma->id); /* Notify the PSC that a reset has occurred */ out_be32(®s->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_ACRB); /* Re-enable RX and TX */ out_8(®s->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE); mutex_unlock(&psc_dma->mutex); msleep(1); psc_ac97_warm_reset(ac97); } Loading