示例#1
0
/*
 * 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;
}
示例#2
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;
}
示例#4
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);
}
示例#5
0
文件: ubi32-gpio.c 项目: 7LK/McWRT
/* 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.
	 */
示例#6
0
/*
 * 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);
}
示例#7
0
/*
 * 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;
}
示例#8
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;
}
示例#9
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
示例#10
0
/*
 * ip7500media_tsc2007_clear_penirq
 */
static void ip7500media_tsc2007_clear_penirq(void)
{
	UBICOM32_IO_PORT(IO_PORT_RD)->int_clr = (1 << 11);
}
示例#11
0
/*
 * 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);
}