MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / arch / arm / mach-s3c24a0 / registers.c
blobcb03bd4719d9345d67585574f84cb445f3d1e4b0
1 /*
2 * arch/arm/mach-s3c24a0/register.c
4 * S3C24A0 register monitor & controller
6 * $Id: registers.c,v 1.3 2006/12/12 13:38:48 gerg Exp $
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file COPYING in the main directory of this archive
10 * for more details.
13 #include <linux/kernel.h>
14 #include <linux/module.h> /* because we are a module */
15 #include <linux/init.h> /* for the __init macros */
16 #include <linux/proc_fs.h> /* all the /proc functions */
17 #include <linux/ioport.h>
18 #include <asm/uaccess.h> /* to copy to/from userspace */
19 #include <asm/arch/hardware.h>
21 #define MODULE_NAME "regmon"
22 #define CPU_DIRNAME "cpu"
23 #define REG_DIRNAME "registers"
25 static ssize_t proc_read_reg(struct file * file, char * buf,
26 size_t nbytes, loff_t *ppos);
27 static ssize_t proc_write_reg(struct file * file, const char * buffer,
28 size_t count, loff_t *ppos);
30 static struct file_operations proc_reg_operations = {
31 read: proc_read_reg,
32 write: proc_write_reg
35 typedef struct elfin_reg_entry {
36 u32 phyaddr;
37 char* name;
38 unsigned short low_ino;
39 } elfin_reg_entry_t;
41 static elfin_reg_entry_t elfin_regs[] =
43 /* { phyaddr, name } */
45 /* PLL clock */
46 {0x40000000, "LOCKTIME"},
47 {0x40000004, "OSCWEST"},
48 {0x40000010, "MPLLCON"},
49 {0x40000014, "UPLLCON"},
50 {0x40000020, "CLKCON"},
51 {0x40000024, "CLKSRC"},
52 {0x40000028, "CLKDIV"},
53 {0x40000030, "PWRMAN"},
54 {0x40000038, "SOFTRESET"},
56 /* INT */
57 {0x40200000, "SRCPND"},
58 {0x40200004, "INTMOD"},
59 {0x40200008, "INTMSK"},
60 {0x4020000c, "PRIORITY"},
61 {0x40200010, "INTPND"},
62 {0x40200014, "INTOFFSET"},
63 {0x40200018, "SUBSRCPND"},
64 {0x4020001c, "INTSUBMSK"},
65 {0x40200020, "VECINTMOD"},
66 {0x40200024, "VECADDR"},
67 {0x40200028, "NVECADDR"},
68 {0x4020002c, "VAR"},
70 /* SROM */
71 {0x40c20000, "SROM_BW"},
72 {0x40c20004, "SROM_BC0"},
73 {0x40c20008, "SROM_BC1"},
74 {0x40c2000c, "SROM_BC2"},
76 /* PWM timer */
77 {0x44000000, "TCFG0"},
78 {0x44000004, "TCFG1"},
79 {0x44000008, "TCON"},
80 {0x4400000c, "TCNTB0"},
81 {0x44000010, "TCMPB0"},
82 {0x44000014, "TCNTO0"},
83 {0x44000018, "TCNTB1"},
84 {0x4400001c, "TCMPB1"},
85 {0x44000020, "TCNTO1"},
86 {0x44000024, "TCNTB2"},
87 {0x44000028, "TCMPB2"},
88 {0x4400002c, "TCNTO2"},
89 {0x44000030, "TCNTB3"},
90 {0x44000034, "TCMPB3"},
91 {0x44000038, "TCNTO3"},
92 {0x4400003c, "TCNTB4"},
93 {0x44000040, "TCNTO4"},
95 /* CamIF */
96 {0x48000004, "CAM_STAY1"},
97 {0x48000008, "CAM_STAY2"},
98 {0x4800000c, "CAM_STAY3"},
99 {0x48000010, "CAM_STAY4"},
100 {0x48000000, "CAM_RDSTAT"},
102 /* Post Processor */
103 {0x4a100000, "VP_MODE"},
104 {0x4a100004, "VP_RATIO_Y"},
105 {0x4a100008, "VP_RATIO_CB"},
106 {0x4a10000c, "VP_RATIO_CR"},
107 {0x4a100010, "VP_SRC_WIDTH"},
108 {0x4a100014, "VP_SRC_HEIGHT"},
109 {0x4a100018, "VP_DST_WIDTH"},
110 {0x4a10001c, "VP_DST_HEIGHT"},
111 {0x4a100020, "VP_START_Y1"},
112 {0x4a100024, "VP_START_Y2"},
113 {0x4a100028, "VP_START_Y3"},
114 {0x4a10002c, "VP_START_Y4"},
115 {0x4a100030, "VP_START_CB1"},
116 {0x4a100034, "VP_START_CB2"},
117 {0x4a100038, "VP_START_CB3"},
118 {0x4a10003c, "VP_START_CB4"},
119 {0x4a100040, "VP_START_CR1"},
120 {0x4a100044, "VP_START_CR2"},
121 {0x4a100048, "VP_START_CR3"},
122 {0x4a10004c, "VP_START_CR4"},
123 {0x4a100050, "VP_START_RGB1"},
124 {0x4a100054, "VP_START_RGB2"},
125 {0x4a100058, "VP_START_RGB3"},
126 {0x4a10005c, "VP_START_RGB4"},
127 {0x4a100060, "VP_END_Y1"},
128 {0x4a100064, "VP_END_Y2"},
129 {0x4a100068, "VP_END_Y3"},
130 {0x4a10006c, "VP_END_Y4"},
131 {0x4a100070, "VP_END_CB1"},
132 {0x4a100074, "VP_END_CB2"},
133 {0x4a100078, "VP_END_CB3"},
134 {0x4a10007c, "VP_END_CB4"},
135 {0x4a100080, "VP_END_CR1"},
136 {0x4a100084, "VP_END_CR2"},
137 {0x4a100088, "VP_END_CR3"},
138 {0x4a10008c, "VP_END_CR4"},
139 {0x4a100090, "VP_END_RGB1"},
140 {0x4a100094, "VP_END_RGB2"},
141 {0x4a100098, "VP_END_RGB3"},
142 {0x4a10009c, "VP_END_RGB4"},
143 {0x4a1000f0, "VP_BYPASS"},
144 {0x4a1000f4, "VP_OFS_Y"},
145 {0x4a1000f8, "VP_OFS_CB"},
146 {0x4a1000fc, "VP_OFS_CR"},
147 {0x4a100100, "VP_OFS_RGB"},
149 /* BUS matrix */
150 {0x40ce0000, "BUS_PRIORITY0"},
151 {0x40ce0004, "BUS_PRIORITY1"},
154 #ifndef ARRAY_SIZE
155 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
156 #endif
158 static int proc_read_reg(struct file * file, char * buf,
159 size_t nbytes, loff_t *ppos)
161 int i_ino = (file->f_dentry->d_inode)->i_ino;
162 char outputbuf[15];
163 int count;
164 int i;
165 elfin_reg_entry_t* current_reg=NULL;
166 if (*ppos>0) /* Assume reading completed in previous read*/
167 return 0;
168 for (i=0;i<ARRAY_SIZE(elfin_regs);i++) {
169 if (elfin_regs[i].low_ino==i_ino) {
170 current_reg = &elfin_regs[i];
171 break;
174 if (current_reg==NULL)
175 return -EINVAL;
177 count = sprintf(outputbuf, "0x%08lx\n",
178 *((volatile unsigned long *) io_p2v(current_reg->phyaddr)));
179 *ppos+=count;
180 if (count>nbytes) /* Assume output can be read at one time */
181 return -EINVAL;
182 if (copy_to_user(buf, outputbuf, count))
183 return -EFAULT;
184 return count;
187 static ssize_t proc_write_reg(struct file * file, const char * buffer,
188 size_t count, loff_t *ppos)
190 int i_ino = (file->f_dentry->d_inode)->i_ino;
191 elfin_reg_entry_t* current_reg=NULL;
192 int i;
193 unsigned long newRegValue;
194 char *endp;
196 for (i=0;i<ARRAY_SIZE(elfin_regs);i++) {
197 if (elfin_regs[i].low_ino==i_ino) {
198 current_reg = &elfin_regs[i];
199 break;
202 if (current_reg==NULL)
203 return -EINVAL;
205 newRegValue = simple_strtoul(buffer,&endp,0);
206 *((volatile unsigned long *) io_p2v(current_reg->phyaddr))=newRegValue;
207 return (count+endp-buffer);
210 static struct proc_dir_entry *regdir;
211 static struct proc_dir_entry *cpudir;
213 static int __init init_reg_monitor(void)
215 struct proc_dir_entry *entry;
216 int i;
218 cpudir = proc_mkdir(CPU_DIRNAME, &proc_root);
219 if (cpudir == NULL) {
220 printk(KERN_ERR MODULE_NAME": can't create /proc/" CPU_DIRNAME "\n");
221 return(-ENOMEM);
224 regdir = proc_mkdir(REG_DIRNAME, cpudir);
225 if (regdir == NULL) {
226 printk(KERN_ERR MODULE_NAME": can't create /proc/" CPU_DIRNAME "/" REG_DIRNAME "\n");
227 return(-ENOMEM);
230 for(i=0;i<ARRAY_SIZE(elfin_regs);i++) {
231 entry = create_proc_entry(elfin_regs[i].name,
232 S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH,
233 regdir);
234 if(entry) {
235 elfin_regs[i].low_ino = entry->low_ino;
236 entry->proc_fops = &proc_reg_operations;
237 } else {
238 printk( KERN_ERR MODULE_NAME
239 ": can't create /proc/" REG_DIRNAME
240 "/%s\n", elfin_regs[i].name);
241 return(-ENOMEM);
244 return (0);
247 static void __exit cleanup_reg_monitor(void)
249 int i;
250 for(i=0;i<ARRAY_SIZE(elfin_regs);i++)
251 remove_proc_entry(elfin_regs[i].name,regdir);
252 remove_proc_entry(REG_DIRNAME, cpudir);
253 remove_proc_entry(CPU_DIRNAME, &proc_root);
256 module_init(init_reg_monitor);
257 module_exit(cleanup_reg_monitor);
259 MODULE_LICENSE("GPL");
261 EXPORT_NO_SYMBOLS;