Mercurial > pt1
comparison driver/pt1_i2c.c @ 142:1e7718cc2556
use utf-8 instead of euc-jp
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Wed, 30 Apr 2014 11:26:24 +0900 |
parents | 2dc994610477 |
children |
comparison
equal
deleted
inserted
replaced
141:c8688d7d6382 | 142:1e7718cc2556 |
---|---|
1 /***************************************************************************/ | 1 /***************************************************************************/ |
2 /* I2C */ | 2 /* I2C情報作成 */ |
3 /***************************************************************************/ | 3 /***************************************************************************/ |
4 #include <linux/module.h> | 4 #include <linux/module.h> |
5 #include <linux/kernel.h> | 5 #include <linux/kernel.h> |
6 #include <linux/errno.h> | 6 #include <linux/errno.h> |
7 #include <linux/pci.h> | 7 #include <linux/pci.h> |
32 static void begin_i2c(void __iomem *, __u32 *, __u32 *); | 32 static void begin_i2c(void __iomem *, __u32 *, __u32 *); |
33 static void start_i2c(void __iomem *, __u32 *, __u32 *, __u32); | 33 static void start_i2c(void __iomem *, __u32 *, __u32 *, __u32); |
34 static void stop_i2c(void __iomem *, __u32 *, __u32 *, __u32, __u32); | 34 static void stop_i2c(void __iomem *, __u32 *, __u32 *, __u32, __u32); |
35 | 35 |
36 | 36 |
37 // PCI˽I2Cǡ | 37 // PCIに書き込むI2Cデータ生成 |
38 void makei2c(void __iomem *regs, __u32 base_addr, __u32 i2caddr, __u32 writemode, __u32 data_en, __u32 clock, __u32 busy) | 38 void makei2c(void __iomem *regs, __u32 base_addr, __u32 i2caddr, __u32 writemode, __u32 data_en, __u32 clock, __u32 busy) |
39 { | 39 { |
40 | 40 |
41 __u32 val ; | 41 __u32 val ; |
42 val = ((base_addr << I2C_DATA) | (writemode << I2C_WRIET_MODE) | | 42 val = ((base_addr << I2C_DATA) | (writemode << I2C_WRIET_MODE) | |
58 writel(WRITE_PULSE, regs); | 58 writel(WRITE_PULSE, regs); |
59 BIT 19, 19+8 ON | 59 BIT 19, 19+8 ON |
60 BIT 16, 16+8 ON | 60 BIT 16, 16+8 ON |
61 BIT 17, 17+8 ON | 61 BIT 17, 17+8 ON |
62 */ | 62 */ |
63 // XC3S | 63 // XC3S初期化 |
64 for(lp = 0 ; lp < PROGRAM_ADDRESS ; lp++){ | 64 for(lp = 0 ; lp < PROGRAM_ADDRESS ; lp++){ |
65 makei2c(regs, lp, 0, READ_EN, DATA_DIS, CLOCK_DIS, BUSY_DIS); | 65 makei2c(regs, lp, 0, READ_EN, DATA_DIS, CLOCK_DIS, BUSY_DIS); |
66 } | 66 } |
67 // XC3S Ԥ (512 PCI Clocks) | 67 // XC3S 初期化待ち (512 PCI Clocks) |
68 for(lp = 0 ; lp < XC3S_PCI_CLOCK ; lp++){ | 68 for(lp = 0 ; lp < XC3S_PCI_CLOCK ; lp++){ |
69 makei2c(regs, 0, 0, READ_EN, DATA_DIS, CLOCK_DIS, BUSY_DIS); | 69 makei2c(regs, 0, 0, READ_EN, DATA_DIS, CLOCK_DIS, BUSY_DIS); |
70 } | 70 } |
71 // ץƥȲ | 71 // プロテクト解除 |
72 // ϲտޤƤ | 72 // これは何を意図しているんだろう? |
73 // ɤɤȽʤ | 73 // 元コードが良く判らない |
74 for(lp = 0 ; lp < 57 ; lp++){ | 74 for(lp = 0 ; lp < 57 ; lp++){ |
75 val = readl(regs); | 75 val = readl(regs); |
76 if(val & I2C_READ_SYNC){ | 76 if(val & I2C_READ_SYNC){ |
77 break ; | 77 break ; |
78 } | 78 } |
118 printk(KERN_ERR "PT1:LOCK FALUT\n"); | 118 printk(KERN_ERR "PT1:LOCK FALUT\n"); |
119 return rc ; | 119 return rc ; |
120 } | 120 } |
121 } | 121 } |
122 | 122 |
123 // ȥऴȤž(OFF) | 123 // ストリームごとの転送制御(OFF) |
124 for(lp = 0 ; lp < MAX_CHANNEL ; lp++){ | 124 for(lp = 0 ; lp < MAX_CHANNEL ; lp++){ |
125 SetStream(regs, lp, 0); | 125 SetStream(regs, lp, 0); |
126 SetStream(regs, lp, 0); | 126 SetStream(regs, lp, 0); |
127 } | 127 } |
128 return 0 ; | 128 return 0 ; |
129 } | 129 } |
130 // | 130 // |
131 // | 131 // |
132 //BIT 0. 1 : Tunerֹ (Enable/Disable) | 132 //BIT 0. 1 : Tuner番号 (Enable/Disable) |
133 //BIT 8. 9 : Tunerֹ | 133 //BIT 8. 9 : Tuner番号 |
134 // | 134 // |
135 // | 135 // |
136 void SetStream(void __iomem *regs, __u32 channel, __u32 enable) | 136 void SetStream(void __iomem *regs, __u32 channel, __u32 enable) |
137 { | 137 { |
138 __u32 val ; | 138 __u32 val ; |
151 int lp ; | 151 int lp ; |
152 | 152 |
153 writel(firstval, regs); | 153 writel(firstval, regs); |
154 writel(secondval, regs); | 154 writel(secondval, regs); |
155 | 155 |
156 // RAMå줿 | 156 // RAMがロックされた? |
157 for(lp = 0 ; lp < XC3S_PCI_CLOCK ; lp++){ | 157 for(lp = 0 ; lp < XC3S_PCI_CLOCK ; lp++){ |
158 val = readl(regs); | 158 val = readl(regs); |
159 if((val & lockval)){ | 159 if((val & lockval)){ |
160 return 0 ; | 160 return 0 ; |
161 } | 161 } |
172 int lp ; | 172 int lp ; |
173 | 173 |
174 val = (readl(regs) & lockval); | 174 val = (readl(regs) & lockval); |
175 writel(firstval, regs); | 175 writel(firstval, regs); |
176 | 176 |
177 // RAMå줿 | 177 // RAMがロックされた? |
178 for(lp = 0 ; lp < 10 ; lp++){ | 178 for(lp = 0 ; lp < 10 ; lp++){ |
179 for(lp = 0 ; lp < 1024 ; lp++){ | 179 for(lp = 0 ; lp < 1024 ; lp++){ |
180 val2 = readl(regs); | 180 val2 = readl(regs); |
181 // ǽ˼ǡȵդˤʤOK | 181 // 最初に取得したデータと逆になればOK |
182 if(((val2 & lockval) != val)){ | 182 if(((val2 & lockval) != val)){ |
183 return 0 ; | 183 return 0 ; |
184 } | 184 } |
185 } | 185 } |
186 schedule_timeout_interruptible(msecs_to_jiffies(1)); | 186 schedule_timeout_interruptible(msecs_to_jiffies(1)); |
222 } | 222 } |
223 old_bits = 1 ; | 223 old_bits = 1 ; |
224 start_i2c(regs, &address, &clock, old_bits); | 224 start_i2c(regs, &address, &clock, old_bits); |
225 old_bits = 0 ; | 225 old_bits = 0 ; |
226 | 226 |
227 // ޤɥ쥹 | 227 // まずアドレスを書く |
228 for(bitpos = 0 ; bitpos < 7 ; bitpos++){ | 228 for(bitpos = 0 ; bitpos < 7 ; bitpos++){ |
229 bits = ((wblock->addr >> (6 - bitpos)) & 1); | 229 bits = ((wblock->addr >> (6 - bitpos)) & 1); |
230 writebits(regs, &address, old_bits, bits); | 230 writebits(regs, &address, old_bits, bits); |
231 old_bits = bits ; | 231 old_bits = bits ; |
232 } | 232 } |
233 // סWRT | 233 // タイプ:WRT |
234 writebits(regs, &address, old_bits, 0); | 234 writebits(regs, &address, old_bits, 0); |
235 // ACK/NACK(ɬ1) | 235 // ACK/NACK用(必ず1) |
236 writebits(regs, &address, 0, 1); | 236 writebits(regs, &address, 0, 1); |
237 | 237 |
238 old_bits = 1 ; | 238 old_bits = 1 ; |
239 // ºݤΥǡ | 239 // 実際のデータを書く |
240 for (lp = 0 ; lp < wblock->count ; lp++){ | 240 for (lp = 0 ; lp < wblock->count ; lp++){ |
241 for(bitpos = 0 ; bitpos < 8 ; bitpos++){ | 241 for(bitpos = 0 ; bitpos < 8 ; bitpos++){ |
242 bits = ((wblock->value[lp] >> (7 - bitpos)) & 1); | 242 bits = ((wblock->value[lp] >> (7 - bitpos)) & 1); |
243 writebits(regs, &address, old_bits, bits); | 243 writebits(regs, &address, old_bits, bits); |
244 old_bits = bits ; | 244 old_bits = bits ; |
245 } | 245 } |
246 // ACK/NACK(ɬ1) | 246 // ACK/NACK用(必ず1) |
247 writebits(regs, &address, old_bits, 1); | 247 writebits(regs, &address, old_bits, 1); |
248 old_bits = 1 ; | 248 old_bits = 1 ; |
249 } | 249 } |
250 | 250 |
251 // Clock negedge | 251 // Clock negedge |
274 } | 274 } |
275 old_bits = 1 ; | 275 old_bits = 1 ; |
276 start_i2c(regs, &address, &clock, old_bits); | 276 start_i2c(regs, &address, &clock, old_bits); |
277 old_bits = 0 ; | 277 old_bits = 0 ; |
278 | 278 |
279 // ޤɥ쥹 | 279 // まずアドレスを書く |
280 for(bitpos = 0 ; bitpos < 7 ; bitpos++){ | 280 for(bitpos = 0 ; bitpos < 7 ; bitpos++){ |
281 bits = ((wblock->addr >> (6 - bitpos)) & 1); | 281 bits = ((wblock->addr >> (6 - bitpos)) & 1); |
282 writebits(regs, &address, old_bits, bits); | 282 writebits(regs, &address, old_bits, bits); |
283 old_bits = bits ; | 283 old_bits = bits ; |
284 } | 284 } |
285 // סWRT | 285 // タイプ:WRT |
286 writebits(regs, &address, old_bits, 0); | 286 writebits(regs, &address, old_bits, 0); |
287 // ACK/NACK(ɬ1) | 287 // ACK/NACK用(必ず1) |
288 writebits(regs, &address, 0, 1); | 288 writebits(regs, &address, 0, 1); |
289 | 289 |
290 old_bits = 1 ; | 290 old_bits = 1 ; |
291 // ºݤΥǡ | 291 // 実際のデータを書く |
292 for (lp = 0 ; lp < wblock->count ; lp++){ | 292 for (lp = 0 ; lp < wblock->count ; lp++){ |
293 for(bitpos = 0 ; bitpos < 8 ; bitpos++){ | 293 for(bitpos = 0 ; bitpos < 8 ; bitpos++){ |
294 bits = ((wblock->value[lp] >> (7 - bitpos)) & 1); | 294 bits = ((wblock->value[lp] >> (7 - bitpos)) & 1); |
295 writebits(regs, &address, old_bits, bits); | 295 writebits(regs, &address, old_bits, bits); |
296 old_bits = bits ; | 296 old_bits = bits ; |
297 } | 297 } |
298 // ACK/NACK(ɬ1) | 298 // ACK/NACK用(必ず1) |
299 writebits(regs, &address, old_bits, 1); | 299 writebits(regs, &address, old_bits, 1); |
300 old_bits = 1 ; | 300 old_bits = 1 ; |
301 } | 301 } |
302 | 302 |
303 // Clock negedge | 303 // Clock negedge |
304 makei2c(regs, address, address + 1, 0, (old_bits ^ 1), 1, 1); | 304 makei2c(regs, address, address + 1, 0, (old_bits ^ 1), 1, 1); |
305 clock = TRUE ; | 305 clock = TRUE ; |
306 address += 1 ; | 306 address += 1 ; |
307 | 307 |
308 // Read | 308 // ここから Read |
309 start_i2c(regs, &address, &clock, old_bits); | 309 start_i2c(regs, &address, &clock, old_bits); |
310 old_bits = 0 ; | 310 old_bits = 0 ; |
311 // ޤɥ쥹 | 311 // まずアドレスを書く |
312 for(bitpos = 0 ; bitpos < 7 ; bitpos++){ | 312 for(bitpos = 0 ; bitpos < 7 ; bitpos++){ |
313 bits = ((wblock->addr >> (6 - bitpos)) & 1); | 313 bits = ((wblock->addr >> (6 - bitpos)) & 1); |
314 writebits(regs, &address, old_bits, bits); | 314 writebits(regs, &address, old_bits, bits); |
315 old_bits = bits ; | 315 old_bits = bits ; |
316 } | 316 } |
317 // סRD | 317 // タイプ:RD |
318 writebits(regs, &address, old_bits, 1); | 318 writebits(regs, &address, old_bits, 1); |
319 // ACK/NACK(ɬ1) | 319 // ACK/NACK用(必ず1) |
320 writebits(regs, &address, 1, 1); | 320 writebits(regs, &address, 1, 1); |
321 | 321 |
322 old_bits = 1 ; | 322 old_bits = 1 ; |
323 // ºݤΥǡ | 323 // 実際のデータを書く |
324 for (lp = 0 ; lp < count ; lp++){ | 324 for (lp = 0 ; lp < count ; lp++){ |
325 for(bitpos = 0 ; bitpos < 8 ; bitpos++){ | 325 for(bitpos = 0 ; bitpos < 8 ; bitpos++){ |
326 writebits(regs, &address, old_bits, 1); | 326 writebits(regs, &address, old_bits, 1); |
327 // Read Mode Set | 327 // Read Mode Set |
328 makei2c(regs, address, address + 1, 1, 0, 0, 1); | 328 makei2c(regs, address, address + 1, 1, 0, 0, 1); |
329 address += 1 ; | 329 address += 1 ; |
330 old_bits = 1 ; | 330 old_bits = 1 ; |
331 } | 331 } |
332 if(lp >= (count - 1)){ | 332 if(lp >= (count - 1)){ |
333 // ACK/NACK(ɬ1) | 333 // ACK/NACK用(必ず1) |
334 writebits(regs, &address, old_bits, 1); | 334 writebits(regs, &address, old_bits, 1); |
335 old_bits = 0 ; | 335 old_bits = 0 ; |
336 }else{ | 336 }else{ |
337 // ACK/NACK(ɬ1) | 337 // ACK/NACK用(必ず1) |
338 writebits(regs, &address, old_bits, 0); | 338 writebits(regs, &address, old_bits, 0); |
339 old_bits = 1 ; | 339 old_bits = 1 ; |
340 } | 340 } |
341 } | 341 } |
342 | 342 |
375 *clock = FALSE ; | 375 *clock = FALSE ; |
376 } | 376 } |
377 | 377 |
378 static void start_i2c(void __iomem *regs, __u32 *address, __u32 *clock, __u32 data) | 378 static void start_i2c(void __iomem *regs, __u32 *address, __u32 *clock, __u32 data) |
379 { | 379 { |
380 // ǡĤäƤʤХǡ | 380 // データが残っていなければデータを下げる |
381 if(!data){ | 381 if(!data){ |
382 // CLOCKCLOCK | 382 // CLOCKがあればCLOCKを下げる |
383 if(*clock != TRUE){ | 383 if(*clock != TRUE){ |
384 *clock = TRUE ; | 384 *clock = TRUE ; |
385 makei2c(regs, *address, *address + 1, 0, 1, 1, 1); | 385 makei2c(regs, *address, *address + 1, 0, 1, 1, 1); |
386 *address += 1 ; | 386 *address += 1 ; |
387 } | 387 } |
399 *clock = FALSE ; | 399 *clock = FALSE ; |
400 } | 400 } |
401 | 401 |
402 static void stop_i2c(void __iomem *regs, __u32 *address, __u32 *clock, __u32 data, __u32 end) | 402 static void stop_i2c(void __iomem *regs, __u32 *address, __u32 *clock, __u32 data, __u32 end) |
403 { | 403 { |
404 // ǡĤäƤ | 404 // データが残っていて |
405 if(data){ | 405 if(data){ |
406 // å | 406 // クロックがあれば |
407 if(*clock != TRUE){ | 407 if(*clock != TRUE){ |
408 *clock = TRUE ; | 408 *clock = TRUE ; |
409 makei2c(regs, *address, *address + 1, 0, 0, 1, 1); | 409 makei2c(regs, *address, *address + 1, 0, 0, 1, 1); |
410 *address += 1; | 410 *address += 1; |
411 } | 411 } |
412 makei2c(regs, *address, *address + 1, 0, 1, 1, 1); | 412 makei2c(regs, *address, *address + 1, 0, 1, 1, 1); |
413 *address += 1 ; | 413 *address += 1 ; |
414 } | 414 } |
415 // åƤ | 415 // クロックが落ちていれば |
416 if(*clock){ | 416 if(*clock){ |
417 *clock = FALSE ; | 417 *clock = FALSE ; |
418 makei2c(regs, *address, *address + 1, 0, 1, 0, 1); | 418 makei2c(regs, *address, *address + 1, 0, 1, 0, 1); |
419 *address += 1 ; | 419 *address += 1 ; |
420 } | 420 } |
431 { | 431 { |
432 | 432 |
433 int lp; | 433 int lp; |
434 __u32 val ; | 434 __u32 val ; |
435 | 435 |
436 // å | 436 // ロックする |
437 mutex_lock(lock); | 437 mutex_lock(lock); |
438 #if 0 | 438 #if 0 |
439 printk(KERN_INFO "Addr=%x(%d)\n", wblock->addr, wblock->count); | 439 printk(KERN_INFO "Addr=%x(%d)\n", wblock->addr, wblock->count); |
440 for(lp = 0 ; lp < wblock->count ; lp++){ | 440 for(lp = 0 ; lp < wblock->count ; lp++){ |
441 printk(KERN_INFO "%x\n", wblock->value[lp]); | 441 printk(KERN_INFO "%x\n", wblock->value[lp]); |
443 printk(KERN_INFO "\n"); | 443 printk(KERN_INFO "\n"); |
444 #endif | 444 #endif |
445 | 445 |
446 blockwrite(regs, wblock); | 446 blockwrite(regs, wblock); |
447 writel(FIFO_GO, regs + FIFO_GO_ADDR); | 447 writel(FIFO_GO, regs + FIFO_GO_ADDR); |
448 //Ȥꤢåʤ褦ˡ | 448 //とりあえずロックしないように。 |
449 for(lp = 0 ; lp < 100 ; lp++){ | 449 for(lp = 0 ; lp < 100 ; lp++){ |
450 val = readl(regs + FIFO_RESULT_ADDR); | 450 val = readl(regs + FIFO_RESULT_ADDR); |
451 if(!(val & FIFO_DONE)){ | 451 if(!(val & FIFO_DONE)){ |
452 break ; | 452 break ; |
453 } | 453 } |
460 { | 460 { |
461 | 461 |
462 int lp; | 462 int lp; |
463 __u32 val ; | 463 __u32 val ; |
464 | 464 |
465 // å | 465 // ロックする |
466 mutex_lock(lock); | 466 mutex_lock(lock); |
467 #if 0 | 467 #if 0 |
468 printk(KERN_INFO "Addr=%x:%d:%d\n", wblock->addr, wblock->count, size); | 468 printk(KERN_INFO "Addr=%x:%d:%d\n", wblock->addr, wblock->count, size); |
469 for(lp = 0 ; lp < wblock->count ; lp++){ | 469 for(lp = 0 ; lp < wblock->count ; lp++){ |
470 printk(KERN_INFO "%x\n", wblock->value[lp]); | 470 printk(KERN_INFO "%x\n", wblock->value[lp]); |