今天想自己写个adc的驱动,发现不清楚系统各个模块的系统时钟如何使用。总不能自己想怎么弄,就怎么弄吧,还是学学框架吧——使用时钟的框架。adc_clock = clk_get(NULL, "adc"); if (!adc_clock) { printk(KERN_ERR "failed to get adc clock source
"); return -ENOENT; } clk_use(adc_clock); clk_enable(adc_clock);上面的这段代码是touchscreen的驱动中的一段,我不清楚,所以去学学系统各个模块时钟的使用方式。在系统的初始化的时候,看见过,但是忘了,再回顾一下。 那是在paging_init()中调用了 mdesc->map_io(), void __init sbc2440_map_io(void) { s3c24xx_init_io(sbc2440_iodesc, ARRAY_SIZE(sbc2440_iodesc)); s3c24xx_init_clocks(12000000); //这个是系统各个部分始终初始化的起点 s3c24xx_init_uarts(sbc2440_uartcfgs, ARRAY_SIZE(sbc2440_uartcfgs)); s3c24xx_set_board(&sbc2440_board); s3c_device_nand.dev.platform_data = &bit_nand_info; }跟 cpu_table 有关,拷贝过来 /* table of supported CPUs */ static const char name_s3c2410[]= "S3C2410"; static const char name_s3c2440[]= "S3C2440"; static const char name_s3c2410a[] = "S3C2410A"; static const char name_s3c2440a[] = "S3C2440A"; static struct cpu_table cpu_ids[] __initdata = { { .idcode= 0x32410000, .idmask= 0xffffffff, .map_io = s3c2410_map_io, .init_clocks = s3c2410_init_clocks, .init_uarts= s3c2410_init_uarts, .init= s3c2410_init, .name = name_s3c2410 }, { .idcode= 0x32410002, .idmask= 0xffffffff, .map_io = s3c2410_map_io, .init_clocks= s3c2410_init_clocks, .init_uarts= s3c2410_init_uarts, .init= s3c2410_init, .name = name_s3c2410a }, { .idcode= 0x32440000, .idmask = 0xffffffff, .map_io = s3c2440_map_io, .init_clocks= s3c2440_init_clocks, .init_uarts = s3c2440_init_uarts, .init = s3c2440_init, .name= name_s3c2440 }, { .idcode= 0x32440001, .idmask= 0xffffffff, .map_io = s3c2440_map_io, .init_clocks= s3c2440_init_clocks, .init_uarts= s3c2440_init_uarts, .init= s3c2440_init, .name= name_s3c2440a } }; 和时钟相关的调用路径: 在 s3c24xx_init_clocks() -> (cpu->init_clocks)(xtal)-> s3c24xx_setup_clocks()这个s3c24xx_setup_clocks()注册了系统的所有时钟,仔细看看它。 在这个函数被调用之前,代码已经根据3C2410_MPLLCON,S3C2410_CLKDIVN寄存器和晶振的频率计算出了fclk,hclk,pclk,他们应该分别是400M,100M,50M。struct clk { struct list_headlist; struct module *owner; struct clk*parent; const char *name; intid; atomic_tused; unsigned long rate; unsigned long ctrlbit; int(*enable)(struct clk *, int enable); };clk数据结构是系统中时钟的抽象,它用list串成一个双向链表,在这个clocks链表里的clk结构,说明是系统中已经注册的,parent表示他的来源,f,h,p之一,name是寻找到某个clk的唯一标识。enable是面向对象的思想的体现,不过,这里没有用到,只是全部被填充为 s3c24xx_clkcon_enable()。/* clock information */ static LIST_HEAD(clocks); static DECLARE_MUTEX(clocks_sem); /* clock definitions */ static struct clk init_clocks[] = { { .name= "nand", .id= -1, .parent= &clk_h, .enable= s3c24xx_clkcon_enable, .ctrlbit= S3C2410_CLKCON_NAND }, { .name= "lcd", .id= -1, .parent= &clk_h, .enable= s3c24xx_clkcon_enable, .ctrlbit= S3C2410_CLKCON_LCDC }, { .name= "usb-host", .id= -1, .parent= &clk_h, .enable= s3c24xx_clkcon_enable, .ctrlbit= S3C2410_CLKCON_USBH }, { .name= "usb-device", .id = -1, /*.parent= &clk_h, */ .parent = &clk_xtal, .enable= s3c24xx_clkcon_enable, .ctrlbit= S3C2410_CLKCON_USBD }, { .name= "timers", .id= -1, .parent= &clk_p, .enable= s3c24xx_clkcon_enable, .ctrlbit = S3C2410_CLKCON_PWMT }, { .name= "sdi", .id= -1, .parent= &clk_p, .enable= s3c24xx_clkcon_enable, .ctrlbit= S3C2410_CLKCON_SDI }, { .name = "uart", .id = 0, .parent= &clk_p, .enable= s3c24xx_clkcon_enable, .ctrlbit= S3C2410_CLKCON_UART0 }, { .name= "uart", .id = 1, .parent= &clk_p, .enable= s3c24xx_clkcon_enable, .ctrlbit = S3C2410_CLKCON_UART1 }, { .name= "uart", .id = 2, .parent= &clk_p, .enable= s3c24xx_clkcon_enable, .ctrlbit = S3C2410_CLKCON_UART2 }, { .name= "gpio", .id = -1, .parent= &clk_p, .enable= s3c24xx_clkcon_enable, .ctrlbit = S3C2410_CLKCON_GPIO }, { .name= "rtc", .id = -1, .parent= &clk_p, .enable= s3c24xx_clkcon_enable, .ctrlbit = S3C2410_CLKCON_RTC }, { .name= "adc", .id = -1, .parent= &clk_p, .enable= s3c24xx_clkcon_enable, .ctrlbit = S3C2410_CLKCON_ADC }, { .name= "i2c", .id = -1, .parent= &clk_p, .enable= s3c24xx_clkcon_enable, .ctrlbit = S3C2410_CLKCON_IIC }, { .name= "iis", .id = -1, .parent= &clk_p, .enable= s3c24xx_clkcon_enable, .ctrlbit = S3C2410_CLKCON_IIS }, { .name= "spi", .id = -1, .parent= &clk_p, .enable= s3c24xx_clkcon_enable, .ctrlbit = S3C2410_CLKCON_SPI }, { .name= "watchdog", .id = -1, .parent= &clk_p, .ctrlbit = 0 } };
收藏该网址