1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
| #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/cdev.h> #include <linux/device.h> #include <asm/io.h> #include <linux/platform_device.h>
dev_t devno; unsigned int major; struct class *pcls; struct device *pdevice;
#define TCFG0 0x0 #define TCFG1 0x04 #define TCON 0x8 #define TCNTB0 0xc #define TCMPB0 0x10
void *pgpd0con; void *ptimer0base;
int Exynos4412_beep_ioremap(struct platform_device *pdev) { pgpd0con = ioremap(pdev->resource[0].start,pdev->resource[0].end-pdev->resource[0].start+1); ptimer0base = ioremap(pdev->resource[1].start,pdev->resource[1].end-pdev->resource[1].start+1);
return 0; }
int Exynos4412_beep_on(void) { writel((readl(ptimer0base+TCON)&(~(0xf<<0)))|(0x9<<0),ptimer0base+TCON); return 0; }
int Exynos4412_beep_off(void) { writel((readl(ptimer0base+TCON)&(~(0x1<<0))),ptimer0base+TCON); return 0; }
#define HZ_BEEP 10000 void Exynos4412_beep_setfre(int fre) { writel(HZ_BEEP/fre,ptimer0base+TCNTB0); writel(HZ_BEEP/(fre*2),ptimer0base+TCMPB0); }
int Exynos4412_beep_init(void) { writel((readl(pgpd0con)&(~(0xf<<0)))|(0x2<<0),pgpd0con);
writel((readl(ptimer0base+TCFG0)&(~(0xff<<0)))|(0xff<<0),ptimer0base+TCFG0); writel((readl(ptimer0base+TCFG1)&(~(0xf<<0)))|(0x1<<0),ptimer0base+TCFG1); writel(1000,ptimer0base+TCNTB0); writel(500,ptimer0base+TCMPB0); writel((readl(ptimer0base+TCON)&(~(0xf<<0)))|(0x2<<0),ptimer0base+TCON); return 0; }
int Exynos4412_beep_open(struct inode* inode,struct file* file) { printk("Exynos4412_beep_open\n"); Exynos4412_beep_on(); return 0; }
int Exynos4412_beep_release(struct inode* inode,struct file* file) { printk("fs4412_beep_close\n"); Exynos4412_beep_off(); return 0; }
#define MAGIC_NUM 'k' #define BEEP_ON _IO(MAGIC_NUM,0) #define BEEP_OFF _IO(MAGIC_NUM,1) #define BEEP_FRE _IO(MAGIC_NUM,2)
long Exynos4412_beep_ioctl(struct file* file,unsigned int cmd, unsigned long arg) { switch(cmd) { case BEEP_ON: Exynos4412_beep_on(); break; case BEEP_OFF: Exynos4412_beep_off(); break;
case BEEP_FRE: Exynos4412_beep_setfre(arg); break; } return 0; }
struct file_operations fops = { .open = Exynos4412_beep_open, .release = Exynos4412_beep_release, .unlocked_ioctl = Exynos4412_beep_ioctl, };
int Exynos4412_beep_probe(struct platform_device *pdev) { int i = 0; printk("Exynos4412_beep_probe\n"); for(;i<pdev->num_resources;i++) { printk("%p\n",pdev->resource[i].start); printk("%p\n",pdev->resource[i].end);
printk("%x\n",pdev->resource[i].flags); } major = register_chrdev(major,"Exynos4412-beep",&fops); devno = MKDEV(major,0); pcls = class_create(THIS_MODULE,"beep-auto"); pdevice = device_create(pcls,NULL,devno,NULL,"Exynos4412-beep");
Exynos4412_beep_ioremap(pdev); Exynos4412_beep_init(); return 0; }
int Exynos4412_beep_remove(struct platform_device *pdev) { printk("Exynos4412_beep_remove\n");
unregister_chrdev(major,"Exynos4412-beep"); device_destroy(pcls,devno); class_destroy(pcls); return 0; }
int Exynos4412_beep_suspend(struct platform_device *pdev,pm_message_t state) { printk("Exynos4412_beep_suspend\n"); return 0; }
int Exynos4412_beep_resume(struct platform_device *pdev) { printk("Exynos4412_beep_resume\n"); return 0; }
struct platform_driver pdrv = { .probe = Exynos4412_beep_probe, .remove = Exynos4412_beep_remove, .suspend = Exynos4412_beep_suspend, .resume = Exynos4412_beep_resume, .driver.name = "Exynos4412-beep"
};
static int __init hello_init(void) { printk("Exynos4412-beep driver init\n"); platform_driver_register(&pdrv); return 0; }
static void __exit hello_exit(void) { printk("exit Exynos4412 beep device\n"); platform_driver_unregister(&pdrv); }
MODULE_LICENSE("GPL"); module_init(hello_init); module_exit(hello_exit);
|