Exemplo n.º 1
0
/** 
 * init_module() - This function is called when the module is loaded
 * 
 * Return: On succes the function retuns a 0 (SUCCES). Otherwise a 
 * negative number is returned.
 */
int init_module(void)
{
	Major = register_chrdev(0, DEVICE_NAME, &fops);
	if (Major < 0) 
	{
		printk(KERN_ALERT "Registering char device failed with %d\n", Major);
		return Major;
	}
    
	printk(KERN_INFO "I was assigned major number %d. To talk to\n", Major);
	printk(KERN_INFO "the driver, create a device file with\n");
        
	printk(KERN_INFO "'mknod /dev/%s c %d 0'.\n", DEVICE_NAME, Major);
	printk(KERN_INFO "Try various minor numbers. Try to echo to\n");
	printk(KERN_INFO "the device file.\n");
	printk(KERN_INFO "Remove the device file and module when done.\n");
    
	gpio = (volatile unsigned int *)ioremap(GPIO_BASE,  1024);
	pwm  = (volatile unsigned int *)ioremap(PWM_BASE,   1024);
	clk  = (volatile unsigned int *)ioremap(CLOCK_BASE, 1024);
	
	// Set pin directions for the output
	INP_GPIO(GPIO_OUTP);
	OUT_GPIO(GPIO_OUTP);
	
	// PWM and clock settings 
	
	SET_GPIO_ALT(GPIO_PWM1, GPIO_ALT);
	
	// stop clock and waiting for busy flag doesn't work, so kill clock
	*(clk + CLK_CTL) = CLK_PASSWD | CLK_CTL_KILL; 
	udelay(10);  
	
	// Set clock divider
	*(clk + CLK_DIV)  = CLK_PASSWD | CLK_DIV_DIVI(96); 
	
	// source=osc and enable clock
	*(clk + CLK_CTL) = CLK_PASSWD | CLK_CTL_ENAB | CLK_CTL_SRC(CLK_CTL_SRC_OSC); 

	// disable PWM and start with a clean register
	*(pwm + PWM_CTL) = 0;
	
	// needs some time until the PWM module gets disabled, without the delay the PWM module crashes
	udelay(10);  
	
	// Set the PWM range
	*(pwm + PWM_RNG2) = 4000;
	
	// Initialize with a 50% dutycycle
	setServo(50);
	
	// start PWM in M/S transmission mode
	*(pwm + PWM_CTL) = PWM_CTL_MSEN2 | PWM_CTL_PWEN2;
	
	interrupt_config();
    
	return SUCCESS;
}
Exemplo n.º 2
0
static int initClock(int clock, int source, int divI, int divF, int MASH)
{
   int ctl[] = {CLK_GP0_CTL, CLK_GP2_CTL};
   int div[] = {CLK_GP0_DIV, CLK_GP2_DIV};
   int src[CLK_SRCS] =
      {CLK_CTL_SRC_PLLD,
       CLK_CTL_SRC_OSC,
       CLK_CTL_SRC_HDMI,
       CLK_CTL_SRC_PLLC};

   int clkCtl, clkDiv, clkSrc;
   uint32_t setting;

   if ((clock  < 0) || (clock  > 1))    return -1;
   if ((source < 0) || (source > 3 ))   return -2;
   if ((divI   < 2) || (divI   > 4095)) return -3;
   if ((divF   < 0) || (divF   > 4095)) return -4;
   if ((MASH   < 0) || (MASH   > 3))    return -5;

   clkCtl = ctl[clock];
   clkDiv = div[clock];
   clkSrc = src[source];

   clkReg[clkCtl] = CLK_PASSWD | CLK_CTL_KILL;

   /* wait for clock to stop */

   while (clkReg[clkCtl] & CLK_CTL_BUSY)
   {
      usleep(10);
   }

   clkReg[clkDiv] =
      (CLK_PASSWD | CLK_DIV_DIVI(divI) | CLK_DIV_DIVF(divF));

   usleep(10);

   clkReg[clkCtl] =
      (CLK_PASSWD | CLK_CTL_MASH(MASH) | CLK_CTL_SRC(clkSrc));

   usleep(10);

   clkReg[clkCtl] |= (CLK_PASSWD | CLK_CTL_ENAB);
}
Exemplo n.º 3
0
int rpi_gpclk_setup(int chan, int source, int div_int, int div_frac)
{
    int MASH = 0;
    uint32_t clksrc;

    if (!rpi_registers_mapping.mapping_initialized)
        return -1;

    if ((source < 0) || (source > sizeof(rpi_gpclk_src_to_reg) /
         sizeof(*rpi_gpclk_src_to_reg) ))
        return -2;

    if ((div_int  < 2) || (div_int   > 4095))
        return -3;

    if ((div_frac < 0) || (div_frac  > 4095))
        return -4;

    if ((MASH   < 0) || (MASH   > 3))
        return -5;

    clksrc = rpi_gpclk_src_to_reg[source];

    CLK_GPx_CTL(chan) = CLK_PASSWD | CLK_CTL_KILL;

    while (CLK_GPx_CTL(chan) & CLK_CTL_BUSY){
        usleep(10);
    }

    CLK_GPx_DIV(chan) = (CLK_PASSWD | CLK_DIV_DIVI(div_int) | CLK_DIV_DIVF(div_frac));

    usleep(10);

    CLK_GPx_CTL(chan) = (CLK_PASSWD | CLK_CTL_MASH(MASH) | CLK_CTL_SRC(clksrc));

    usleep(10);

    CLK_GPx_CTL(chan) |= (CLK_PASSWD | CLK_CTL_ENAB);

    return 0;
}