Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(544)

Side by Side Diff: drivers/media/video/samsung/tv20/cec_s5pv210.c

Issue 2036011: V4L/DVB : Add S5PV210 TV out driver support (Closed) Base URL: swsolcc@12.23.106.100:kernel-samsung.git
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « drivers/media/video/samsung/tv20/cec_s5pv210.h ('k') | drivers/media/video/samsung/tv20/ddc.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* linux/drivers/media/video/samsung/tv20/cec_s5pv210.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5PV210 - cec ftn file for Samsung TVOut driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15
16 #include <linux/io.h>
17
18 #include <mach/map.h>
19 #include <mach/regs-clock.h>
20 #include <mach/regs-cec.h>
21 #include "cec.h"
22
23 #ifdef CECDEBUG
24 #define CECPRINTK(fmt, args...) \
25 printk(KERN_INFO "\t\t[CEC] %s: " fmt, __func__ , ## args)
26 #else
27 #define CECPRINTK(fmt, args...)
28 #endif
29
30 static struct resource *cec_mem;
31 void __iomem *cec_base;
32
33 #define S5P_HDMI_FIN 24000000
34 #define CEC_DIV_RATIO 187500
35
36 void tv_cec_set_divider(void)
37 {
38 u32 div_ratio, reg, div_val;
39
40 div_ratio = S5P_HDMI_FIN/CEC_DIV_RATIO - 1;
41
42 reg = readl(S5P_HDMI_PHY_CONTROL);
43 reg = (reg & ~(0x3FF<<16)) | (div_ratio << 16);
44
45 writel(reg, S5P_HDMI_PHY_CONTROL);
46
47 div_val = CEC_DIV_RATIO * 0.00005 - 1;
48
49 writeb(0x0, cec_base + CEC_DIVISOR_3);
50 writeb(0x0, cec_base + CEC_DIVISOR_2);
51 writeb(0x0, cec_base + CEC_DIVISOR_1);
52 writeb(div_val, cec_base + CEC_DIVISOR_0);
53
54 CECPRINTK("CEC_DIVISOR_3 = 0x%08x\n", readb(cec_base + CEC_DIVISOR_3));
55 CECPRINTK("CEC_DIVISOR_2 = 0x%08x\n", readb(cec_base + CEC_DIVISOR_2));
56 CECPRINTK("CEC_DIVISOR_1 = 0x%08x\n", readb(cec_base + CEC_DIVISOR_1));
57 CECPRINTK("CEC_DIVISOR_0 = 0x%08x\n", readb(cec_base + CEC_DIVISOR_0));
58 }
59
60 void tv_cec_enable_rx(void)
61 {
62 u8 reg;
63 reg = readb(cec_base + CEC_RX_CTRL);
64 reg |= CEC_RX_CTRL_ENABLE;
65 writeb(reg, cec_base + CEC_RX_CTRL);
66
67 CECPRINTK("CEC_RX_CTRL = 0x%08x \n", readb(cec_base + CEC_RX_CTRL));
68 }
69
70 void tv_cec_mask_rx_interrupts(void)
71 {
72 u8 reg;
73 reg = readb(cec_base + CEC_IRQ_MASK);
74 reg |= CEC_IRQ_RX_DONE;
75 reg |= CEC_IRQ_RX_ERROR;
76 writeb(reg, cec_base + CEC_IRQ_MASK);
77
78 CECPRINTK("CEC_IRQ_MASK = 0x%08x \n", readb(cec_base + CEC_IRQ_MASK));
79 }
80
81 void tv_cec_unmask_rx_interrupts(void)
82 {
83 u8 reg;
84 reg = readb(cec_base + CEC_IRQ_MASK);
85 reg &= ~CEC_IRQ_RX_DONE;
86 reg &= ~CEC_IRQ_RX_ERROR;
87 writeb(reg, cec_base + CEC_IRQ_MASK);
88
89 CECPRINTK("CEC_IRQ_MASK = 0x%08x \n", readb(cec_base + CEC_IRQ_MASK));
90 }
91
92 void tv_cec_mask_tx_interrupts(void)
93 {
94 u8 reg;
95 reg = readb(cec_base + CEC_IRQ_MASK);
96 reg |= CEC_IRQ_TX_DONE;
97 reg |= CEC_IRQ_TX_ERROR;
98 writeb(reg, cec_base + CEC_IRQ_MASK);
99
100 CECPRINTK("CEC_IRQ_MASK = 0x%08x \n", readb(cec_base + CEC_IRQ_MASK));
101
102 }
103
104 void tv_cec_unmask_tx_interrupts(void)
105 {
106 u8 reg;
107 reg = readb(cec_base + CEC_IRQ_MASK);
108 reg &= ~CEC_IRQ_TX_DONE;
109 reg &= ~CEC_IRQ_TX_ERROR;
110 writeb(reg, cec_base + CEC_IRQ_MASK);
111
112 CECPRINTK("CEC_IRQ_MASK = 0x%08x \n", readb(cec_base + CEC_IRQ_MASK));
113 }
114
115 void tv_cec_reset(void)
116 {
117 writeb(CEC_RX_CTRL_RESET, cec_base + CEC_RX_CTRL); /* reset CEC Rx */
118 writeb(CEC_TX_CTRL_RESET, cec_base + CEC_TX_CTRL); /* reset CEC Tx */
119
120 CECPRINTK("CEC_RX_CTRL = 0x%08x \n", readb(cec_base + CEC_RX_CTRL));
121 CECPRINTK("CEC_TX_CTRL = 0x%08x \n", readb(cec_base + CEC_TX_CTRL));
122 }
123
124 void tv_cec_tx_reset(void)
125 {
126 writeb(CEC_TX_CTRL_RESET, cec_base + CEC_TX_CTRL); /* reset CEC Tx */
127
128 CECPRINTK("CEC_TX_CTRL = 0x%08x \n", readb(cec_base + CEC_TX_CTRL));
129 }
130
131 void tv_cec_rx_reset(void)
132 {
133 writeb(CEC_RX_CTRL_RESET, cec_base + CEC_RX_CTRL); /* reset CEC Rx */
134 CECPRINTK("CEC_RX_CTRL = 0x%08x \n", readb(cec_base + CEC_RX_CTRL));
135 }
136
137 void tv_cec_threshold(void)
138 {
139 writeb(CEC_FILTER_THRESHOLD, cec_base + CEC_RX_FILTER_TH);
140 /* setup filter */
141 writeb(0, cec_base + CEC_RX_FILTER_CTRL);
142 CECPRINTK("CEC_RX_FILTER_TH = 0x%08x \n",
143 readb(cec_base + CEC_RX_FILTER_TH));
144 }
145
146 void tv_cec_copy_packet(char *data, size_t count)
147 {
148 int i = 0;
149 u8 reg;
150 /* copy packet to hardware buffer */
151 while (i < count) {
152 writeb(data[i], cec_base + (CEC_TX_BUFF0 + (i*4)));
153 i++;
154 }
155
156 /* set number of bytes to transfer */
157 writeb(count, cec_base + CEC_TX_BYTES);
158
159 tv_cec_set_tx_state(STATE_TX);
160
161 /* start transfer */
162 reg = readb(cec_base + CEC_TX_CTRL);
163
164 reg |= CEC_TX_CTRL_START;
165
166 /* if message is broadcast message - set corresponding bit */
167 if ((data[0] & CEC_MESSAGE_BROADCAST_MASK) == CEC_MESSAGE_BROADCAST)
168 reg |= CEC_TX_CTRL_BCAST;
169 else
170 reg &= ~CEC_TX_CTRL_BCAST;
171
172 /* set number of retransmissions */
173 reg |= 0x50;
174
175 writeb(reg, cec_base + CEC_TX_CTRL);
176 }
177
178 void tv_cec_set_addr(u32 addr)
179 {
180 writeb(addr & 0x0F, cec_base + CEC_LOGIC_ADDR);
181
182 }
183
184 u32 tv_cec_get_status(void)
185 {
186 u32 status = 0;
187
188 status = readb(cec_base + CEC_STATUS_0);
189 status |= readb(cec_base + CEC_STATUS_1) << 8;
190 status |= readb(cec_base + CEC_STATUS_2) << 16;
191 status |= readb(cec_base + CEC_STATUS_3) << 24;
192
193 CECPRINTK("status = 0x%x!\n", status);
194
195 return status;
196 }
197
198 void tv_clr_pending_tx(void)
199 {
200 /* clear interrupt pending bit */
201 writeb(CEC_IRQ_TX_DONE | CEC_IRQ_TX_ERROR, cec_base + CEC_IRQ_CLEAR);
202 }
203
204 void tv_clr_pending_rx(void)
205 {
206 /* clear interrupt pending bit */
207 writeb(CEC_IRQ_RX_DONE | CEC_IRQ_RX_ERROR, cec_base + CEC_IRQ_CLEAR);
208 }
209
210 void tv_cec_get_rx_buf(u32 size, u8 *buffer)
211 {
212 u32 i = 0;
213
214 while (i < size) {
215 buffer[i] = readb(cec_base + CEC_RX_BUFF0 + (i * 4));
216 i++;
217 }
218 }
219
220 void __init tv_cec_probe(struct platform_device *pdev)
221 {
222 struct resource *res;
223 size_t size;
224
225 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
226
227 if (res == NULL) {
228 dev_err(&pdev->dev,
229 "failed to get memory region resource for cec\n");
230 goto cec_err;
231
232 }
233
234 size = (res->end - res->start) + 1;
235
236 cec_mem = request_mem_region(res->start, size, pdev->name);
237
238 if (cec_mem == NULL) {
239 dev_err(&pdev->dev,
240 "failed to get memory region for cec\n");
241 goto cec_err;
242
243 }
244
245 cec_base = ioremap(res->start, size);
246
247 if (cec_base == NULL) {
248 dev_err(&pdev->dev,
249 "failed to ioremap address region for cec\n");
250 goto cec_err;
251
252
253 }
254
255 return;
256
257 cec_err:
258 dev_err(&pdev->dev,
259 "failed to cec_probe()\n");
260
261 }
262
263 int __init tv_cec_release(struct platform_device *pdev)
264 {
265 iounmap(cec_base);
266
267 /* remove memory region */
268 if (cec_mem != NULL) {
269 if (release_resource(cec_mem))
270 dev_err(&pdev->dev,
271 "Can't remove tvout drv !!\n");
272
273 kfree(cec_mem);
274
275 cec_mem = NULL;
276 }
277
278 return 0;
279 }
OLDNEW
« no previous file with comments | « drivers/media/video/samsung/tv20/cec_s5pv210.h ('k') | drivers/media/video/samsung/tv20/ddc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698