📄 em9010.c
字号:
#define __NO_VERSION__#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/string.h>#include <linux/timer.h>#include <linux/delay.h>#include <linux/errno.h>#include <linux/slab.h>#include <linux/version.h>#include <linux/string.h>#include <linux/pci.h>#include <asm/io.h>#include <asm/uaccess.h>#include <linux/i2c-algo-bit.h>#include <linux/time.h>#include "em8300_reg.h"#include <linux/em8300.h>/* sub_2ac2d */static int testcable(struct em8300_s *em){ int attempts; attempts = 0; while (em9010_read(em, 0x0) & 0x20) { if(attempts++ > 100) { return 0; } mdelay(1); } attempts = 0; while (!(em9010_read(em, 0x0) & 0x20)) { if(attempts++ > 100) { return 0; } mdelay(1); } return 1;} /* loc_2abac */int em9010_cabledetect(struct em8300_s *em){ em9010_write(em,0xb, 0xc8); em9010_write(em,0x9, 0x4); em9010_write(em,0xd, 0x44); if (testcable(em)) { return 1; } em9010_write(em, 0xd, 0x4c); if (testcable(em)) { return 1; } em9010_write(em, 0x9, 0x0); return 0;}/* sub_2AC2D locals: a = [ebp-8]*//* computes `a - b' and write the result in `result', assumes `a >= b' */static inline void my_timeval_less(struct timeval a, struct timeval b, struct timeval * result){ if (a.tv_usec < b.tv_usec) { a.tv_sec--; a.tv_usec += 1000000; } result->tv_sec = a.tv_sec - b.tv_sec; result->tv_usec = a.tv_usec - b.tv_usec;}static int sub_2AC2D(struct em8300_s *em){ int a; struct timeval t,t2,tr; do_gettimeofday(&t); a=1000; while (em9010_read(em, 0x0) & 0x20) { if (!a--) { do_gettimeofday(&t2); my_timeval_less(t2, t, &tr); if (tr.tv_usec >= 50*1000) return(0); a=1000; } } do_gettimeofday(&t); a=1000; while (!(em9010_read(em,0x0) & 0x20)) { if (!a--) { do_gettimeofday(&t2); my_timeval_less(t2, t, &tr); if(tr.tv_usec >= 50*1000) return(0); a=1000; } } return(1); }/* sub_4288C Arguments pa = [ebp+0x8] pb = [ebp+0xc] pc = [ebp+0x10] pd = [ebp+0x14] pe = [ebp+0x18] pf = [ebp+0x1c] pg = [ebp+0x20] ph = [ebp+0x24] */void sub_4288c(struct em8300_s *em, int pa, int pb, int pc, int pd, int pe, int pf, int pg, int ph){ int pav, pbv, pcv, pdv, i; /* pr_debug("sub_4288c: xpos=%d, ypos=%d, xwin=%d, ywin=%d, xoff=%d, yoff=%d, xcorr=%d, xd=%d\n", pa,pb,pc,pd,pe,pf,pg,ph); */ if (pg >= 800) { if (ph) { pb >>= 1; pd >>= 1; pf >>= 1; } if (pa < 0) { pav = 0; pcv = pc + pa; } else { pav = pa; pcv = pc; } if (pb < 0) { pbv = 0; pdv = pd + pb; } else { pbv = pb; pdv = pd; } if (pav+pcv>em->overlay_xres) { pcv=em->overlay_xres-pav; } if (pb+pd > em->overlay_yres) { pdv=em->overlay_yres-pb; } pa = (pa * 1000) / pg; pc = (pc * 1000) / pg; pav = (pav * 1000) / pg; pcv = (pcv * 1000) / pg; if (read_ucregister(DICOM_UpdateFlag) == 1) { i=0; while ((read_ucregister(DICOM_UpdateFlag) == 1) & (i < 20)) { udelay(50); i++; } if (read_ucregister(DICOM_UpdateFlag) == 1) { write_ucregister(DICOM_UpdateFlag, 0); udelay(50); } } write_ucregister(DICOM_VisibleLeft, pe+pav); write_ucregister(DICOM_VisibleRight, pe+pav+pcv-1); write_ucregister(DICOM_VisibleTop, pf+pbv); write_ucregister(DICOM_VisibleBottom, pf+pbv+pdv-1); write_ucregister(DICOM_FrameLeft, pe+pa); write_ucregister(DICOM_FrameRight, pe+pa+pc-1); write_ucregister(DICOM_FrameTop, pf+pb); write_ucregister(DICOM_FrameBottom, pf+pb+pd-1); write_ucregister(DICOM_UpdateFlag,1); }}static int loc_2BE50(struct em8300_s *em){ em9010_write(em, 0xb, 0xc8); sub_2AC2D(em); sub_2AC2D(em); if (read_register(0x1f4b) < (2*em->overlay_yres / 3)) { return 1; } else { return 0; }}int em9010_calibrate_yoffset(struct em8300_s *em){ int i; pr_debug("em9010: Starting yoffset calibration\n"); //clear the stability value em9010_write(em, 0x6, 0x0); em->overlay_a[EM9010_ATTRIBUTE_XCORR] = em->overlay_xcorr_default; em->overlay_a[EM9010_ATTRIBUTE_XOFFSET] = 100000 / em->overlay_a[EM9010_ATTRIBUTE_XCORR]; em->overlay_a[EM9010_ATTRIBUTE_YOFFSET] = 4; em9010_write(em, 0xb, 0x14); em9010_write16(em, 0x8, 0x2000); em9010_write16(em, 0x10, 0x2000); em9010_write16(em, 0x20, 0xff20); em9010_write(em, 0xa, 0x6); em8300_video_setplaymode(em, EM8300_PLAYMODE_FRAMEBUF ); if (em->overlay_double_y) { em8300_dicom_fill_dispbuffers(em, 0, 0, em->dbuf_info.xsize, 4, 0xffffffff, 0x80808080 ); } else { em8300_dicom_fill_dispbuffers(em, 0, 0, em->dbuf_info.xsize, 2, 0xffffffff, 0x80808080 ); } sub_4288c(em, 0, 0, em->dbuf_info.xsize, em->dbuf_info.ysize, em->overlay_a[EM9010_ATTRIBUTE_XOFFSET], em->overlay_a[EM9010_ATTRIBUTE_YOFFSET], em->overlay_a[EM9010_ATTRIBUTE_XCORR], em->overlay_double_y); pr_debug("em9010: Done drawing y testpattern\n"); mdelay(20); if (!sub_2AC2D(em)) { return 0; } em9010_write(em, 0, 0x14); em9010_write(em, 0, 0x10); for (i=0; i < 60; i++) { if (!sub_2AC2D(em)) { pr_debug("em9010: sub_2AC2D failed\n"); return 0; } if (! (em9010_read(em,0) & 4)) { sub_4288c(em, 0, i, em->dbuf_info.xsize, em->dbuf_info.ysize, em->overlay_a[EM9010_ATTRIBUTE_XOFFSET], em->overlay_a[EM9010_ATTRIBUTE_YOFFSET], em->overlay_a[EM9010_ATTRIBUTE_XCORR], em->overlay_double_y); if (!sub_2AC2D(em)) { return 0; } } else { break; } } if (i == 60) { return 0; } em->overlay_a[EM9010_ATTRIBUTE_YOFFSET] = em->overlay_a[EM9010_ATTRIBUTE_YOFFSET]+i-2; if (em->overlay_double_y) { em->overlay_a[EM9010_ATTRIBUTE_YOFFSET] >>= 1; } pr_debug("em9010: Sucessfully calibrated yoffset (%d)\n", em->overlay_a[EM9010_ATTRIBUTE_YOFFSET]); return 1;}int em9010_calibrate_xoffset(struct em8300_s *em){ int i; em9010_write(em, 0xb, 0x14); em9010_write16(em, 0x8, 0x2000); em9010_write16(em, 0x10, 0x2000); em9010_write16(em, 0x20, 0xff20); em9010_write(em, 0xa, 0x6); em8300_dicom_fill_dispbuffers(em, 0, 0, em->dbuf_info.xsize, 4, 0, 0x80808080 ); em8300_dicom_fill_dispbuffers(em, 2, 0, 2, em->dbuf_info.ysize, 0xffffffff, 0x80808080 ); em->overlay_a[EM9010_ATTRIBUTE_XCORR] = 1000; em->overlay_a[EM9010_ATTRIBUTE_XOFFSET] = 100000 / em->overlay_a[EM9010_ATTRIBUTE_XCORR]; sub_4288c(em, 0, 0, em->dbuf_info.xsize, em->dbuf_info.ysize, em->overlay_a[EM9010_ATTRIBUTE_XOFFSET], em->overlay_a[EM9010_ATTRIBUTE_YOFFSET], em->overlay_a[EM9010_ATTRIBUTE_XCORR], em->overlay_double_y); pr_debug("em9010: Done drawing x testpattern\n"); mdelay(20); if (!sub_2AC2D(em)) { return 0; } em9010_write(em, 0, 0x14); em9010_write(em, 0, 0x10); for (i=0; i < 220; i++) { if (!sub_2AC2D(em)) { pr_debug("em9010: sub_2AC2D failed\n"); return 0; } if (! (em9010_read(em,0) & 4)) { sub_4288c(em, i, 0, em->dbuf_info.xsize, em->dbuf_info.ysize, em->overlay_a[EM9010_ATTRIBUTE_XOFFSET], em->overlay_a[EM9010_ATTRIBUTE_YOFFSET], em->overlay_a[EM9010_ATTRIBUTE_XCORR], em->overlay_double_y); if (!sub_2AC2D(em)) { return 0; } } else { break; } } if (i == 220) { return 0; } em->overlay_a[EM9010_ATTRIBUTE_XOFFSET] = em->overlay_a[EM9010_ATTRIBUTE_XOFFSET]+i; pr_debug("em9010: Sucessfully calibrated xoffset (%d)\n", em->overlay_a[EM9010_ATTRIBUTE_XOFFSET]); return 1;}static int color_cal(struct em8300_s *em,int ul, int a, int b, int c,int d, int *res){ int i; if (ul == 1) { /* Measure upper threshold level */ em9010_write16(em, a, d << 8); em9010_write(em, 0xa, b); if (!sub_2AC2D(em)) { return 0; } em9010_write(em, 0, 0x17); em9010_write(em, 0, 0x10); for (i=d; i > 0; i--) { em9010_write16(em, a, i << 8); if (em9010_read(em, 0) & (a >> 3)) { break; } else { continue; } } } else if (ul == 2) { /* Measure lower threshold level */ em9010_write16(em, a, 0x0); em9010_write(em, 0xa, c); if (!sub_2AC2D(em)) { return 0; } em9010_write(em, 0, 0x17); em9010_write(em, 0, 0x10); for (i=0; i < d; i++) { em9010_write16(em, a, i); if (em9010_read(em, 0) & (a >> 3)) { break; } else { continue; } } } else { return -1; } *res = i; return 1;}int em9010_calibrate_xcorrection(struct em8300_s *em){ int i,j; em9010_write(em, 0xb, 0x14); em9010_write16(em, 0x8, 0x2000); em9010_write16(em, 0x10, 0x2000); em9010_write16(em, 0x20, 0xff20);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -