static void hr222_config_akm(struct pcxhr_mgr *mgr, unsigned short data) { unsigned short mask = 0x8000; /* activate access to codec registers */ PCXHR_INPB(mgr, PCXHR_XLX_HIFREQ); while (mask) { PCXHR_OUTPB(mgr, PCXHR_XLX_DATA, data & mask ? PCXHR_DATA_CODEC : 0); mask >>= 1; } /* termiate access to codec registers */ PCXHR_INPB(mgr, PCXHR_XLX_RUER); }
static void hr222_config_akm(struct pcxhr_mgr *mgr, unsigned short data) { unsigned short mask = 0x8000; PCXHR_INPB(mgr, PCXHR_XLX_HIFREQ); while (mask) { PCXHR_OUTPB(mgr, PCXHR_XLX_DATA, data & mask ? PCXHR_DATA_CODEC : 0); mask >>= 1; } PCXHR_INPB(mgr, PCXHR_XLX_RUER); }
int hr222_sub_init(struct pcxhr_mgr *mgr) { unsigned char reg; mgr->board_has_analog = 1; /* analog always available */ mgr->xlx_cfg = PCXHR_CFG_SYNCDSP_MASK; reg = PCXHR_INPB(mgr, PCXHR_XLX_STATUS); if (reg & PCXHR_STAT_MIC_CAPS) mgr->board_has_mic = 1; /* microphone available */ snd_printdd("MIC input available = %d\n", mgr->board_has_mic); /* reset codec */ PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, PCXHR_DSP_RESET_DSP); msleep(5); mgr->dsp_reset = PCXHR_DSP_RESET_DSP | PCXHR_DSP_RESET_MUTE | PCXHR_DSP_RESET_CODEC; PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, mgr->dsp_reset); /* hr222_write_gpo(mgr, 0); does the same */ msleep(5); /* config AKM */ hr222_config_akm(mgr, AKM_POWER_CONTROL_CMD); hr222_config_akm(mgr, AKM_CLOCK_INF_55K_CMD); hr222_config_akm(mgr, AKM_UNMUTE_CMD); hr222_config_akm(mgr, AKM_RESET_OFF_CMD); /* init micro boost */ hr222_micro_boost(mgr, 0); return 0; }
int hr222_sub_init(struct pcxhr_mgr *mgr) { unsigned char reg; mgr->board_has_analog = 1; mgr->xlx_cfg = PCXHR_CFG_SYNCDSP_MASK; reg = PCXHR_INPB(mgr, PCXHR_XLX_STATUS); if (reg & PCXHR_STAT_MIC_CAPS) mgr->board_has_mic = 1; snd_printdd("MIC input available = %d\n", mgr->board_has_mic); PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, PCXHR_DSP_RESET_DSP); msleep(5); mgr->dsp_reset = PCXHR_DSP_RESET_DSP | PCXHR_DSP_RESET_MUTE | PCXHR_DSP_RESET_CODEC; PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, mgr->dsp_reset); msleep(5); hr222_config_akm(mgr, AKM_POWER_CONTROL_CMD); hr222_config_akm(mgr, AKM_CLOCK_INF_55K_CMD); hr222_config_akm(mgr, AKM_UNMUTE_CMD); hr222_config_akm(mgr, AKM_RESET_OFF_CMD); hr222_micro_boost(mgr, 0); return 0; }
static int hr222_set_hw_capture_level(struct pcxhr_mgr *mgr, int level_l, int level_r, int level_mic) { /* program all input levels at the same time */ unsigned int data; int i; if (!mgr->capture_chips) return -EINVAL; /* no PCX22 */ data = ((level_mic & 0xff) << 24); /* micro is mono, but apply */ data |= ((level_mic & 0xff) << 16); /* level on both channels */ data |= ((level_r & 0xff) << 8); /* line input right channel */ data |= (level_l & 0xff); /* line input left channel */ PCXHR_INPB(mgr, PCXHR_XLX_DATA); /* activate input codec */ /* send 32 bits (4 x 8 bits) */ for (i = 0; i < 32; i++, data <<= 1) { PCXHR_OUTPB(mgr, PCXHR_XLX_DATA, (data & 0x80000000) ? PCXHR_DATA_CODEC : 0); } PCXHR_INPB(mgr, PCXHR_XLX_RUER); /* close input level codec */ return 0; }
static int hr222_set_hw_capture_level(struct pcxhr_mgr *mgr, int level_l, int level_r, int level_mic) { unsigned int data; int i; if (!mgr->capture_chips) return -EINVAL; data = ((level_mic & 0xff) << 24); data |= ((level_mic & 0xff) << 16); data |= ((level_r & 0xff) << 8); data |= (level_l & 0xff); PCXHR_INPB(mgr, PCXHR_XLX_DATA); for (i = 0; i < 32; i++, data <<= 1) { PCXHR_OUTPB(mgr, PCXHR_XLX_DATA, (data & 0x80000000) ? PCXHR_DATA_CODEC : 0); } PCXHR_INPB(mgr, PCXHR_XLX_RUER); return 0; }