📄 em8300_ucode.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 "em8300_reg.h"#include <linux/em8300.h>#include <linux/soundcard.h>#include "em8300_reg.c"staticint upload_block(struct em8300_s *em, int blocktype, int offset, int len, unsigned char *buf){ int i, val; switch (blocktype) { case 4: offset *= 2; em->mem[0x1c11] = offset & 0xffff; em->mem[0x1c12] = (offset >> 16) & 0xffff; em->mem[0x1c13] = len; em->mem[0x1c14] = len; em->mem[0x1c15] = 0; em->mem[0x1c16] = 1; em->mem[0x1c17] = 1; em->mem[0x1c18] = offset & 0xffff; em->mem[0x1c19] = (offset >> 16) & 0xffff; em->mem[0x1c1a] = 1; for (i=0; i < len; i+=4) { val = (buf[i+2] << 24) | (buf[i+3] << 16) | (buf[i] << 8) | buf[i+1]; em->mem[0x11800] = val; } if (em8300_waitfor(em, 0x1c1a, 0, 1)) { return -ETIME; } break; case 1: for (i=0; i < len; i+=4) { val = (buf[i+1] << 24) | (buf[i] << 16) | (buf[i+3] << 8) | buf[i+2]; em->mem[offset/2 + i/4] = val; } break; case 2: for (i=0; i < len; i+=2) { val = (buf[i+1] << 8) | buf[i]; em->mem[0x1000 + offset + i/2] = val; } break; } return 0;}staticint upload_prepare(struct em8300_s *em){ em->mem[0x30000] = 0x1ff00; em->mem[0x1f50] = 0x123; em->mem[0x20001] = 0x0; em->mem[0x2000] = 0x2; em->mem[0x2000] = 0x0; em->mem[0x1ff8] = 0xffff; em->mem[0x1ff9] = 0xffff; em->mem[0x1ff8] = 0xff00; em->mem[0x1ff9] = 0xff00; if (em->chip_revision == 1) { em->mem[0x1c04] = 0x8c7; em->mem[0x1c00] = 0x80; em->mem[0x1c04] = 0xc7; } em->mem[0x1c04] = em->var_ucode_reg3; em->mem[0x1c00] = em->var_ucode_reg1; em->mem[0x1c04] = em->var_ucode_reg2; em->mem[0x1c08]; em->mem[0x1c10] = 0x8; em->mem[0x1c20] = 0x8; em->mem[0x1c30] = 0x8; em->mem[0x1c40] = 0x8; em->mem[0x1c50] = 0x8; em->mem[0x1c60] = 0x8; em->mem[0x1c70] = 0x8; em->mem[0x1c80] = 0x8; em->mem[0x1c90] = 0x10; em->mem[0x1ca0] = 0x10; em->mem[0x1cb0] = 0x8; em->mem[0x1cc0] = 0x8; em->mem[0x1cd0] = 0x8; em->mem[0x1ce0] = 0x8; em->mem[0x1c01] = 0x5555; em->mem[0x1c02] = 0x55a; em->mem[0x1c03] = 0x0; return 0;}int em8300_ucode_upload(struct em8300_s *em, void *ucode_user, int ucode_size){ int flags,offset,len; unsigned char *ucode,*p; int memcount,i; char regname[128]; ucode = kmalloc(ucode_size, GFP_KERNEL); if (!ucode) { return -ENOMEM; } upload_prepare(em); copy_from_user(ucode, ucode_user, ucode_size); memcount=0; p = ucode; while (memcount < ucode_size) { flags = p[0] | (p[1] << 8); p+=2; offset = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); p+=4; len = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); p+=4; memcount+=10; len *= 2; if (!flags) break; switch (flags & 0xf00) { case 0: upload_block(em, flags, offset, len, p); break; case 0x200: for (i=0;i < len; i++) { if(p[i]) { regname[i] = p[i] ^ 0xff; } else { break; } } regname[i]=0; for (i=0; i < MAX_UCODE_REGISTER; i++) { if (!strcmp(ucodereg_names[i], regname)) { em->ucode_regs[i] = 0x1000 + offset; break; } } break; } memcount += len; p += len; } kfree(ucode); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -