/* * snd_ubi32_cs4384_set_rate */ static int snd_ubi32_cs4384_set_rate(struct ubi32_snd_priv *priv, int rate) { struct ubi32_cs4384_platform_data *cpd = priv->pdata->priv_data; unsigned int div = 0; const u16_t mult[] = {64, 96, 128, 192, 256, 384, 512, 768, 1024}; int i; int j; struct ubicom32_io_port *io; switch (cpd->mclk_src) { case UBI32_CS4384_MCLK_PWM_Q_G5_0: case UBI32_CS4384_MCLK_PWM_Q_G5_1: case UBI32_CS4384_MCLK_PWM_Q_G4_30: case UBI32_CS4384_MCLK_PWM_Q_G4_31: io = UBICOM32_IO_PORT(RQ); break; case UBI32_CS4384_MCLK_PWM_R_G5_2: case UBI32_CS4384_MCLK_PWM_R_G5_3: io = UBICOM32_IO_PORT(RR); break; case UBI32_CS4384_MCLK_PWM_S_G5_0: case UBI32_CS4384_MCLK_PWM_S_G5_1: io = UBICOM32_IO_PORT(RS); break; case UBI32_CS4384_MCLK_PWM_T_G5_2: case UBI32_CS4384_MCLK_PWM_T_G5_3: io = UBICOM32_IO_PORT(RT); break; case UBI32_CS4384_MCLK_OTHER: return 0; default: return -EINVAL; } for (i = 0; i < sizeof(mult) / sizeof(u16_t); i++) { for (j = 0; j < cpd->n_mclk; j++) { if (((unsigned int)rate * (unsigned int)mult[i]) == cpd->mclk_entries[j].rate) { div = cpd->mclk_entries[j].div; break; } } } if (!div) { return -EINVAL; } io->ctl1 = ((div - 1) << 16) | (div / 2); return 0; }
/* * ip7160rgwlcd_tsc2007_init_platform_hw */ static int ip7160rgwlcd_tsc2007_init_platform_hw(void) { int res = gpio_request(GPIO_RA_5, "TSC2007_IRQ"); if (res) { return res; } UBICOM32_IO_PORT(RA)->ctl0 &= ~(0x03 << 17); UBICOM32_IO_PORT(RA)->ctl0 |= (0x02 << 17); return 0; }
/* * ip7500media_tsc2007_init_platform_hw */ static int ip7500media_tsc2007_init_platform_hw(void) { int res = gpio_request(GPIO_RD_1, "TSC2007_IRQ"); if (res) { return res; } UBICOM32_IO_PORT(IO_PORT_RD)->function = 0; UBICOM32_IO_PORT(IO_PORT_RD)->int_mask = (1 << 11); UBICOM32_IO_PORT(IO_PORT_RD)->ctl2 &= ~(0x03 << 16); UBICOM32_IO_PORT(IO_PORT_RD)->ctl2 |= (0x02 << 16); return 0; }
/* * ip7160rgwlcd_tsc2007_exit_platform_hw */ static void ip7160rgwlcd_tsc2007_exit_platform_hw(void) { UBICOM32_IO_PORT(RA)->ctl0 &= ~(0x03 << 17); gpio_free(GPIO_RA_5); }
/* There are 9 ports, A through I. Not all 32 bits in each * port can be a GPIO, but we pretend they are. Its up to the * programmer to refer to the processor data sheet. */ #define MAX_UBICOM_GPIOS (9 * 32) /* ARCH_NR_GPIOS */ #define NUM_GPIO_PORTS (gpio_bank(MAX_UBICOM_GPIOS)) /* GPIO reservation bit map array */ static int reserved_gpio_map[NUM_GPIO_PORTS]; /* Array of hardware io_port addresses */ static struct ubicom32_io_port *gpio_bank_addr[NUM_GPIO_PORTS] = { UBICOM32_IO_PORT(RA), UBICOM32_IO_PORT(RB), UBICOM32_IO_PORT(RC), UBICOM32_IO_PORT(RD), UBICOM32_IO_PORT(RE), UBICOM32_IO_PORT(RF), UBICOM32_IO_PORT(RG), UBICOM32_IO_PORT(RH), UBICOM32_IO_PORT(RI) }; struct ubi_gpio_chip { /* * Right now, nothing else lives here. */
/* * tviu800_tsc2007_exit_platform_hw */ static void tviu800_tsc2007_exit_platform_hw(void) { UBICOM32_IO_PORT(RA)->ctl0 &= ~(0x03 << 19); gpio_free(GPIO_RA_6); }
/* * snd_ubi32_cs4384_setup_mclk */ static int snd_ubi32_cs4384_setup_mclk(struct ubi32_cs4384_platform_data *pdata) { struct ubicom32_io_port *io; struct ubicom32_gpio_port *gpio = UBICOM32_GPIO_PORT(PG5); unsigned int mask; int fn; unsigned int div = pdata->mclk_entries[0].div; unsigned int fn_sel; switch (pdata->mclk_src) { case UBI32_CS4384_MCLK_PWM_Q_G5_0: mask = (1 << 0); io = UBICOM32_IO_PORT(RQ); fn = 2; break; case UBI32_CS4384_MCLK_PWM_Q_G5_1: mask = (1 << 1); io = UBICOM32_IO_PORT(RQ); fn = 2; break; case UBI32_CS4384_MCLK_PWM_Q_G4_30: mask = (1 << 30); io = UBICOM32_IO_PORT(RQ); gpio = UBICOM32_GPIO_PORT(PG4); fn = 3; break; case UBI32_CS4384_MCLK_PWM_Q_G4_31: mask = (1 << 31); io = UBICOM32_IO_PORT(RQ); gpio = UBICOM32_GPIO_PORT(PG4); fn = 3; break; case UBI32_CS4384_MCLK_PWM_R_G5_2: mask = (1 << 2); io = UBICOM32_IO_PORT(RR); fn = 2; break; case UBI32_CS4384_MCLK_PWM_R_G5_3: mask = (1 << 3); io = UBICOM32_IO_PORT(RR); fn = 2; break; case UBI32_CS4384_MCLK_PWM_S_G5_0: mask = (1 << 0); io = UBICOM32_IO_PORT(RS); fn = 1; break; case UBI32_CS4384_MCLK_PWM_S_G5_1: mask = (1 << 1); io = UBICOM32_IO_PORT(RS); fn = 1; break; case UBI32_CS4384_MCLK_PWM_T_G5_2: mask = (1 << 2); io = UBICOM32_IO_PORT(RT); fn = 1; break; case UBI32_CS4384_MCLK_PWM_T_G5_3: mask = (1 << 3); io = UBICOM32_IO_PORT(RT); fn = 1; break; case UBI32_CS4384_MCLK_OTHER: return 0; default: return -EINVAL; } /* * Check to see if the pin is busy so we don't clobber any functions */ fn_sel = gpio->fn_sel[0] | gpio->fn_sel[1] | gpio->fn_sel[2] | gpio->fn_sel[3]; if (fn_sel & mask) { printk(KERN_WARNING DRIVER_NAME ": MCLK pin in use\n"); return -EBUSY; } io->function = (1 << 24) | 1; io->ctl1 = ((div - 1) << 16) | (div / 2); gpio->gpio_ctl |= mask; gpio->fn_sel[fn] |= mask; return 0; }
/* * ubicom32bl_init_hw_pwm * Set the appropriate PWM registers */ static int ubicom32bl_init_hw_pwm(struct ubicom32bl_data *ud) { if (ud->pdata->pwm_channel > UBICOM32BL_NUM_PWM_CHANNELS) { return -ENODEV; } #if UBICOM32BL_NUM_PWM_CHANNELS # ifdef IP7000 { /* * bit 13: enable */ u16_t pwm_cfg = (1 << 13) | (ud->pdata->pwm_prescale << 8) ; switch (ud->pdata->pwm_channel) { case 0: /* * Channel 0 is in the lower half of PORT C ctl0 and ctl1 (PA5) */ UBICOM32_IO_PORT(IO_PORT_RC)->ctl0 &= ~0xFFFF; UBICOM32_IO_PORT(IO_PORT_RC)->ctl0 |= pwm_cfg; UBICOM32_IO_PORT(IO_PORT_RC)->ctl1 = ud->pdata->pwm_period << 16; /* * If the port function is not set, set it to GPIO/PWM */ if (!UBICOM32_IO_PORT(IO_PORT_RA)->function) { UBICOM32_IO_PORT(IO_PORT_RA)->function = 3; } UBICOM32_GPIO_DISABLE(GPIO_RA_5); break; case 1: /* * Channel 1 is in the upper half of PORT C ctl0 and ctl2 (PE4) */ UBICOM32_IO_PORT(IO_PORT_RC)->ctl0 &= ~0xFFFF0000; UBICOM32_IO_PORT(IO_PORT_RC)->ctl0 |= (pwm_cfg << 16); UBICOM32_IO_PORT(IO_PORT_RC)->ctl2 = ud->pdata->pwm_period << 16; /* * If the port function is not set, set it to GPIO/ExtIOInt */ if (!UBICOM32_IO_PORT(IO_PORT_RE)->function) { UBICOM32_IO_PORT(IO_PORT_RE)->function = 3; } UBICOM32_GPIO_DISABLE(GPIO_RE_4); break; case 2: /* * Channel 2 is in PORT H ctl0 and ctl1 (PD0) */ UBICOM32_IO_PORT(IO_PORT_RH)->ctl0 &= ~0xFFFF0000; UBICOM32_IO_PORT(IO_PORT_RH)->ctl0 = pwm_cfg; UBICOM32_IO_PORT(IO_PORT_RH)->ctl1 = ud->pdata->pwm_period << 16; /* * If the port function is not set, set it to GPIO */ if (!UBICOM32_IO_PORT(IO_PORT_RD)->function) { UBICOM32_IO_PORT(IO_PORT_RD)->function = 3; } UBICOM32_GPIO_DISABLE(GPIO_RD_0); break; } } # elif IP8000 { struct ubicom32_io_port *port = UBICOM32_IO_PORT(IO_PORT_RQ + (ud->pdata->pwm_channel * 0x4000)); struct ubicom32_gpio_port *gpio = UBICOM32_PORT_NUM_TO_GPIO(gpio_bank(ud->pdata->gpio)); unsigned int mask = 0; /* * Check to see if the pin is busy so we don't clobber any functions */ u32_t fn_sel = gpio->fn_sel[0] | gpio->fn_sel[1] | gpio->fn_sel[2] | gpio->fn_sel[3]; if (fn_sel & gpio_bit(ud->pdata->gpio)) { printk(KERN_WARNING DRIVER_NAME ": GPIO %d in use %08x\n", ud->pdata->gpio, fn_sel); return -EBUSY; } switch (ud->pdata->pwm_channel) { case 0: /* * PWM Q can go on PG4[30](fn4), PG4[31](fn4), PG5[0](fn3), PG5[1](fn3) */ if (ud->pdata->gpio == GPIO_PG4_30) { mask = (1 << 30); gpio->fn_sel[3] |= mask; } else if (ud->pdata->gpio == GPIO_PG4_31) { mask = (1 << 31); gpio->fn_sel[3] |= mask; } else if (ud->pdata->gpio == GPIO_PG5_0) { mask = (1 << 0); gpio->fn_sel[2] |= mask; } else if (ud->pdata->gpio != GPIO_PG5_1) { mask = (1 << 1); gpio->fn_sel[2] |= mask; } else { printk(KERN_WARNING DRIVER_NAME ": GPIO %d invalid for pwm channel %d\n", ud->pdata->gpio, ud->pdata->pwm_channel); return -EINVAL; } break; case 1: /* * PWM R can go on PG5[3](fn3), PG5[2](fn3) */ if (ud->pdata->gpio == GPIO_PG5_3) { mask = (1 << 3); gpio->fn_sel[2] |= mask; } else if (ud->pdata->gpio != GPIO_PG5_2) { mask = (1 << 2); gpio->fn_sel[2] |= mask; } else { printk(KERN_WARNING DRIVER_NAME ": GPIO %d invalid for pwm channel %d\n", ud->pdata->gpio, ud->pdata->pwm_channel); return -EINVAL; } break; case 2: /* * PWM S can go on PG5[1](fn2), PG5[0](fn2) */ if (ud->pdata->gpio == GPIO_PG5_1) { mask = (1 << 1); gpio->fn_sel[1] |= mask; } else if (ud->pdata->gpio != GPIO_PG5_0) { mask = (1 << 0); gpio->fn_sel[1] |= mask; } else { printk(KERN_WARNING DRIVER_NAME ": GPIO %d invalid for pwm channel %d\n", ud->pdata->gpio, ud->pdata->pwm_channel); return -EINVAL; } break; case 3: /* * PWM T can go on PG5[3](fn2), PG5[2](fn2) */ if (ud->pdata->gpio == GPIO_PG5_3) { mask = (1 << 3); gpio->fn_sel[1] |= mask; } else if (ud->pdata->gpio != GPIO_PG5_2) { mask = (1 << 2); gpio->fn_sel[1] |= mask; } else { printk(KERN_WARNING DRIVER_NAME ": GPIO %d invalid for pwm channel %d\n", ud->pdata->gpio, ud->pdata->pwm_channel); return -EINVAL; } break; } /* * PWM is clocked at clk_core / (2 ^ pwm_prescale[3:0]) */ port->function = 1<<24 | 1; port->ctl0 = (ud->pdata->pwm_prescale << 8) ; gpio->gpio_ctl |= mask; } # endif #endif return 0; }
{ ud->cur_intensity = intensity ? 255 : 0; if (intensity) { gpio_set_value(ud->pdata->gpio, !ud->pdata->invert); return 0; } gpio_set_value(ud->pdata->gpio, ud->pdata->invert); return 0; } #ifdef IP7000 #define UBICOM32BL_NUM_PWM_CHANNELS 3 static volatile u32_t *ubicom32bl_channel_ctl[] = { &(UBICOM32_IO_PORT(IO_PORT_RC)->ctl1), &(UBICOM32_IO_PORT(IO_PORT_RC)->ctl2), &(UBICOM32_IO_PORT(IO_PORT_RH)->ctl1), }; #elif IP8000 #define UBICOM32BL_NUM_PWM_CHANNELS 4 static volatile u32_t *ubicom32bl_channel_ctl[] = { &(UBICOM32_IO_PORT(IO_PORT_RQ)->ctl1), &(UBICOM32_IO_PORT(IO_PORT_RR)->ctl1), &(UBICOM32_IO_PORT(IO_PORT_RS)->ctl1), &(UBICOM32_IO_PORT(IO_PORT_RT)->ctl1), }; #else #define UBICOM32BL_NUM_PWM_CHANNELS 0 #endif
/* * ip7500media_tsc2007_clear_penirq */ static void ip7500media_tsc2007_clear_penirq(void) { UBICOM32_IO_PORT(IO_PORT_RD)->int_clr = (1 << 11); }
/* * ip7500media_tsc2007_exit_platform_hw */ static void ip7500media_tsc2007_exit_platform_hw(void) { UBICOM32_IO_PORT(IO_PORT_RD)->int_mask &= ~(1 << 11); UBICOM32_IO_PORT(IO_PORT_RD)->ctl2 &= ~(0x03 << 16); gpio_free(GPIO_RD_1); }