#include "dib3000-common.h" int dib3000_read_reg(struct dib3000_state *state, u16 reg) { u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff }; u8 rb[2]; struct i2c_msg msg[] = { { .addr = state->config->demod_address, .flags = 0, .buf = wb, .len = 2 }, { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 }, }; if (i2c_transfer(state->i2c, msg, 2) != 2) deb_alot("i2c read error\n"); deb_alot("reading from i2c bus (reg: %d 0x%x, val: %d 0x%x)\n",reg,reg, (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]); return (rb[0] << 8) | rb[1]; } int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val) { u8 b[] = { (reg >> 8) & 0xff, reg & 0xff, (val >> 8) & 0xff, val & 0xff, }; struct i2c_msg msg[] = { { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = 4 } }; deb_alot("writing to i2c bus (reg: %d, val: %d)\n",reg,val); return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0; } int dib3000_init_pid_list(struct dib3000_state *state, int num) { int i; if (state != NULL) { state->pid_list = kmalloc(sizeof(struct dib3000_pid) * num,GFP_KERNEL); if (state->pid_list == NULL) return -ENOMEM; deb_info("initializing %d pids for the pid_list.\n",num); state->pid_list_lock = SPIN_LOCK_UNLOCKED; memset(state->pid_list,0,num*(sizeof(struct dib3000_pid))); for (i=0; i < num; i++) { state->pid_list[i].pid = 0; state->pid_list[i].active = 0; } state->feedcount = 0; } else return -EINVAL; return 0; } void dib3000_dealloc_pid_list(struct dib3000_state *state) { if (state != NULL && state->pid_list != NULL) kfree(state->pid_list); } /* fetch a pid from pid_list */ int dib3000_get_pid_index(struct dib3000_pid pid_list[], int num_pids, int pid, spinlock_t *pid_list_lock,int onoff) { int i,ret = -1; unsigned long flags; spin_lock_irqsave(pid_list_lock,flags); for (i=0; i < num_pids; i++) if (onoff) { if (!pid_list[i].active) { pid_list[i].pid = pid; pid_list[i].active = 1; ret = i; break; } } else { if (pid_list[i].active && pid_list[i].pid == pid) { pid_list[i].pid = 0; pid_list[i].active = 0; ret = i; break; } } deb_info("pid: %d, on: %d, index: %d\n",pid,onoff,ret); spin_unlock_irqrestore(pid_list_lock,flags); return ret; } int dib3000_search_status(u16 irq,u16 lock) { if (irq & 0x02) { if (lock & 0x01) { deb_setf("auto search succeeded\n"); return 1; // auto search succeeded } else { deb_setf("auto search not successful\n"); return 0; // auto search failed } } else if (irq & 0x01) { deb_setf("auto search failed\n"); return 0; // auto search failed } return -1; // try again } /* for auto search */ u16 dib3000_seq[2][2][2] = /* fft,gua, inv */ { /* fft */ { /* gua */ { 0, 1 }, /* 0 0 { 0,1 } */ { 3, 9 }, /* 0 1 { 0,1 } */ }, { { 2, 5 }, /* 1 0 { 0,1 } */ { 6, 11 }, /* 1 1 { 0,1 } */ } }; EXPORT_SYMBOL(dib3000_seq); EXPORT_SYMBOL(dib3000_read_reg); EXPORT_SYMBOL(dib3000_write_reg); EXPORT_SYMBOL(dib3000_init_pid_list); EXPORT_SYMBOL(dib3000_dealloc_pid_list); EXPORT_SYMBOL(dib3000_get_pid_index); EXPORT_SYMBOL(dib3000_search_status);