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 $
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
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
= {
35 typedef struct elfin_reg_entry
{
38 unsigned short low_ino
;
41 static elfin_reg_entry_t elfin_regs
[] =
43 /* { phyaddr, name } */
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"},
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"},
71 {0x40c20000, "SROM_BW"},
72 {0x40c20004, "SROM_BC0"},
73 {0x40c20008, "SROM_BC1"},
74 {0x40c2000c, "SROM_BC2"},
77 {0x44000000, "TCFG0"},
78 {0x44000004, "TCFG1"},
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"},
96 {0x48000004, "CAM_STAY1"},
97 {0x48000008, "CAM_STAY2"},
98 {0x4800000c, "CAM_STAY3"},
99 {0x48000010, "CAM_STAY4"},
100 {0x48000000, "CAM_RDSTAT"},
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"},
150 {0x40ce0000, "BUS_PRIORITY0"},
151 {0x40ce0004, "BUS_PRIORITY1"},
155 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
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
;
165 elfin_reg_entry_t
* current_reg
=NULL
;
166 if (*ppos
>0) /* Assume reading completed in previous read*/
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
];
174 if (current_reg
==NULL
)
177 count
= sprintf(outputbuf
, "0x%08lx\n",
178 *((volatile unsigned long *) io_p2v(current_reg
->phyaddr
)));
180 if (count
>nbytes
) /* Assume output can be read at one time */
182 if (copy_to_user(buf
, outputbuf
, 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
;
193 unsigned long newRegValue
;
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
];
202 if (current_reg
==NULL
)
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
;
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");
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");
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
,
235 elfin_regs
[i
].low_ino
= entry
->low_ino
;
236 entry
->proc_fops
= &proc_reg_operations
;
238 printk( KERN_ERR MODULE_NAME
239 ": can't create /proc/" REG_DIRNAME
240 "/%s\n", elfin_regs
[i
].name
);
247 static void __exit
cleanup_reg_monitor(void)
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");