int d2083_audio_hs_preamp_gain(enum d2083_preamp_gain_val hsgain_val) { u8 regval = 0; int ret = 0; dlg_info("d2083_audio_hs_preamp_gain hs_pre_gain=0x%x \n",hsgain_val); //if(0 < hsgain_val && D2083_PREAMP_GAIN_MUTE > hsgain_val ) //dlg_audio->hs_pre_gain = hsgain_val; if(0 > hsgain_val || D2083_PREAMP_GAIN_MUTE < hsgain_val ) { dlg_info("[%s]- Invalid preamp gain, so set to 0dB \n", __func__); hsgain_val = D2083_PREAMP_GAIN_0DB; } if(dlg_audio->HSenabled==true) { #ifdef USE_AUDIO_DIFFERENTIAL if(!dlg_audio->IHFenabled) { regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL; regval |= (hsgain_val << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL; ret = audio_write(D2083_PREAMP_A_CTRL1_REG,regval); } #endif regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL; regval |= (hsgain_val << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL; ret = audio_write(D2083_PREAMP_B_CTRL1_REG,regval); } dlg_audio->hs_pre_gain = hsgain_val; return ret; }
int d2083_audio_hs_set_gain(enum d2083_audio_output_sel hs_path_sel, enum d2083_hp_vol_val hs_gain_val) { int ret = 0; u8 regval; if(D2083_HPVOL_NEG_57DB > hs_gain_val || D2083_HPVOL_MUTE < hs_gain_val) { dlg_info("[%s]- Invalid gain, so set to -1dB \n", __func__); hs_gain_val = D2083_HPVOL_NEG_1DB; } dlg_info("d2083_audio_hs_set_gain path=%d hs_pga_gain=0x%x \n", hs_path_sel, hs_gain_val); if(dlg_audio->HSenabled==true) { if (hs_path_sel & D2083_OUT_HPL) { regval = audio_read(D2083_HP_L_GAIN_REG) & ~D2042_HP_AMP_GAIN; ret |= audio_write(D2083_HP_L_GAIN_REG, regval | (hs_gain_val & D2042_HP_AMP_GAIN)); ret |= audio_clear_bits(D2083_HP_L_CTRL_REG, D2083_HP_AMP_MUTE_EN); } if (hs_path_sel & D2083_OUT_HPR) { regval = audio_read(D2083_HP_R_GAIN_REG) & ~D2042_HP_AMP_GAIN; ret |= audio_write(D2083_HP_R_GAIN_REG, regval | (hs_gain_val & D2042_HP_AMP_GAIN)); ret |= audio_clear_bits(D2083_HP_R_CTRL_REG, D2083_HP_AMP_MUTE_EN); } } dlg_audio->hs_pga_gain=hs_gain_val; return ret; }
static ssize_t d2083_ioctl_write(struct file *file, const char __user *buffer, size_t len, loff_t *offset) { struct d2083 *d2083 = file->private_data; struct pmu_debug dbg; char cmd[MAX_USER_INPUT_LEN]; int ret, i; dlg_info("%s\n", __func__); if (!d2083) { dlg_err("%s: driver not initialized\n", __func__); return -EINVAL; } if (len > MAX_USER_INPUT_LEN) len = MAX_USER_INPUT_LEN; if (copy_from_user(cmd, buffer, len)) { dlg_err("%s: copy_from_user failed\n", __func__); return -EFAULT; } /* chop of '\n' introduced by echo at the end of the input */ if (cmd[len - 1] == '\n') cmd[len - 1] = '\0'; if (d2083_dbg_parse_args(cmd, &dbg) < 0) { d2083_dbg_usage(); return -EINVAL; } dlg_info("operation: %s\n", (dbg.read_write == PMUDBG_READ_REG) ? "read" : "write"); dlg_info("address : 0x%x\n", dbg.addr); dlg_info("length : %d\n", dbg.len); if (dbg.read_write == PMUDBG_READ_REG) { ret = d2083_read(d2083, dbg.addr, dbg.len, dbg.val); if (ret < 0) { dlg_err("%s: pmu reg read failed\n", __func__); return -EFAULT; } for (i = 0; i < dbg.len; i++, dbg.addr++) dlg_info("[%x] = 0x%02x\n", dbg.addr, dbg.val[i]); } else { ret = d2083_write(d2083, dbg.addr, dbg.len, dbg.val); if (ret < 0) { dlg_err("%s: pmu reg write failed\n", __func__); return -EFAULT; } } *offset += len; return len; }
int d2083_audio_hs_ihf_poweroff(void) { int ret = 0; u8 regval; if(ihf_power_status ==0){ return ret; } ihf_power_status = 0; dlg_info("%s, HP =%d, status:%d \n", __func__,dlg_audio->HSenabled,ihf_power_status); audio_write(D2083_SP_CTRL_REG,0x32); #ifdef USE_AUDIO_DIFFERENTIAL if (dlg_audio->HSenabled == false) #endif { regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL; regval |= (D2083_PREAMP_MUTE); regval &= (~D2083_PREAMP_EN); ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval); } audio_write(D2083_SP_PWR_REG, 0x00); audio_write(D2083_SP_NON_CLIP_ZC_REG, 0x00); audio_write(D2083_SP_NON_CLIP_REG, 0x00); audio_write(D2083_SP_NG1_REG, 0x00); audio_write(D2083_SP_NG2_REG, 0x00); dlg_audio->IHFenabled = false; //if(dlg_audio->HSenabled==false) // audio_write(D2083_LDO_AUD_MCTL_REG, 0x00); //AUD_LDO off return ret; }
static unsigned int d2041_regulator_get_mode(struct regulator_dev *rdev) { struct d2041 *d2041 = rdev_get_drvdata(rdev); unsigned int regulator_id = rdev_get_id(rdev); unsigned int mode = 0; if (regulator_id >= D2041_NUMBER_OF_REGULATORS) return -EINVAL; mode = get_regulator_mctl_mode(d2041, regulator_id); /* Map d2041 regulator mode to Linux framework mode */ switch(mode) { case REGULATOR_MCTL_TURBO: mode = REGULATOR_MODE_FAST; break; case REGULATOR_MCTL_ON: mode = REGULATOR_MODE_NORMAL; break; case REGULATOR_MCTL_SLEEP: mode = REGULATOR_MODE_IDLE; break; case REGULATOR_MCTL_OFF: mode = REGULATOR_MODE_STANDBY; break; default: /* unsupported or unknown mode */ break; } dlg_info("[REGULATOR] : [%s] >> MODE(%d)\n", __func__, mode); return mode; }
/* TODO Set mode is it software controlled? if yes then following implementation is useful ?? if no then we dont need following implementation ?? */ static int d2041_regulator_set_mode(struct regulator_dev *rdev, unsigned int mode) { struct d2041 *d2041 = rdev_get_drvdata(rdev); unsigned int regulator_id = rdev_get_id(rdev); int ret; u8 mctl_mode; dlg_info("[REGULATOR] : regulator_set_mode. mode is %d\n", mode); switch(mode) { case REGULATOR_MODE_FAST : mctl_mode = REGULATOR_MCTL_TURBO; break; case REGULATOR_MODE_NORMAL : mctl_mode = REGULATOR_MCTL_ON; break; case REGULATOR_MODE_IDLE : mctl_mode = REGULATOR_MCTL_SLEEP; break; case REGULATOR_MODE_STANDBY: mctl_mode = REGULATOR_MCTL_OFF; break; default: return -EINVAL; } ret = set_regulator_mctl_mode(d2041, regulator_id, mode); return ret; }
/* D2083 poweroff function */ void d2083_system_poweroff(void) { dlg_info("%s\n", __func__); if(d2083_dev_info) { d2083_shutdown(d2083_dev_info); } }
int d2083_audio_ihf_preamp_gain(enum d2083_preamp_gain_val ihfgain_val) { u8 regval; dlg_info("d2083_audio_ihf_preamp_gain gain=%d \n", ihfgain_val); if(0 > ihfgain_val || D2083_PREAMP_GAIN_MUTE < ihfgain_val ) { dlg_info("[%s]- Invalid preamp gain, so set to 0dB \n", __func__); ihfgain_val = D2083_PREAMP_GAIN_0DB; } regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL; regval |= (ihfgain_val << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL; return audio_write(D2083_PREAMP_A_CTRL1_REG,regval); }
int d2083_shutdown(struct d2083 *d2083) { u8 dst; //int ret; int last_adc; dlg_info("%s\n", __func__); if (d2083->read_dev == NULL) return -ENODEV; last_adc=d2083_get_last_vbat_adc(); d2083_reg_write(d2083, D2083_GPID3_REG, (0xFF&last_adc)); //8 LSB d2083_reg_write(d2083, D2083_GPID4_REG, (0xF&(last_adc>>8))); // 4 MSB last_adc=d2083_get_last_temp_adc(); d2083_reg_write(d2083, D2083_GPID5_REG, (0xFF&last_adc)); //8 LSB d2083_reg_write(d2083, D2083_GPID6_REG, (0xF&(last_adc>>8))); // 4 MSB d2083_clear_bits(d2083,D2083_CONTROLB_REG,D2083_CONTROLB_OTPREADEN); //otp reload disable d2083_clear_bits(d2083,D2083_POWERCONT_REG,D2083_POWERCONT_MCTRLEN); //mctl disable d2083_reg_write(d2083, D2083_BUCK1_REG, 0x54); //buck1 1.0 V 0x14 // 20120221 Go deepsleep : Manual LDO off d2083_reg_write(d2083, D2083_IRQMASKB_REG, 0x0); //onkey mask clear // buck4, ldo1, ldo3, ldo6, 7, 8, 9, 11, 13, 14, 15, 16, 17 d2083_clear_bits(d2083, D2083_LDO1_REG, (1<<6)); //LDO 1 disable d2083_clear_bits(d2083, D2083_LDO3_REG, (1<<6)); //LDO 3 disable d2083_clear_bits(d2083, D2083_LDO6_REG, (1<<6)); //LDO 6 disable d2083_clear_bits(d2083, D2083_LDO7_REG, (1<<6)); //LDO 7 disable d2083_clear_bits(d2083, D2083_LDO8_REG, (1<<6)); //LDO 8 disable d2083_clear_bits(d2083, D2083_LDO9_REG, (1<<6)); //LDO 9 disable d2083_clear_bits(d2083, D2083_LDO11_REG, (1<<6)); //LDO 11 disable d2083_clear_bits(d2083, D2083_LDO13_REG, (1<<6)); //LDO 13 disable d2083_clear_bits(d2083, D2083_LDO14_REG, (1<<6)); //LDO 14 disable d2083_clear_bits(d2083, D2083_LDO15_REG, (1<<6)); //LDO 15 disable d2083_clear_bits(d2083, D2083_LDO16_REG, (1<<6)); //LDO 16 disable d2083_clear_bits(d2083, D2083_LDO17_REG, (1<<6)); //LDO 17 disable d2083_clear_bits(d2083, D2083_LDO_AUD_REG, (1<<6)); //LDO_AUD disable d2083_reg_write(d2083, D2083_BUCK4_REG, 0x0); //BUCK 4 d2083_reg_write(d2083, D2083_SUPPLY_REG, 0x10); d2083_reg_write(d2083, D2083_POWERCONT_REG, 0x0E); d2083_reg_write(d2083, D2083_PDDIS_REG, 0xCF); d2083_reg_read(d2083, D2083_CONTROLB_REG, &dst); dst |= D2083_CONTROLB_DEEPSLEEP; d2083_reg_write(d2083, D2083_CONTROLB_REG, dst); return 0; }
int d2083_set_hs_noise_gate(u16 regval) { int ret = 0; #ifdef NOISE_GATE_USE dlg_info("d2083_set_hs_noise_gate regval=%d \n",regval); if(dlg_audio->HSenabled==true) { ret |= audio_write(D2083_HP_NG1_REG, (u8)(regval & 0x00FF)); ret |= audio_write(D2083_HP_NG2_REG, (u8)((regval >> 8) & 0x00FF)); }
int d2083_audio_hs_ihf_set_gain(enum d2083_sp_vol_val ihfgain_val) { u8 regval; dlg_info("[%s]-ihfgain_val[0x%x]\n", __func__, ihfgain_val); if(0 > ihfgain_val || D2083_SPVOL_MUTE < ihfgain_val) { dlg_info("[%s]- Invalid gain, so set to 4dB \n", __func__); ihfgain_val = D2083_SPVOL_0DB; } regval = audio_read(D2083_SP_CTRL_REG); if (ihfgain_val == D2083_SPVOL_MUTE) { regval |= D2083_SP_MUTE; } else { regval &= ~(D2083_SP_VOL | D2083_SP_MUTE); regval |= (ihfgain_val << D2083_SP_VOL_SHIFT) & D2083_SP_VOL; } return audio_write(D2083_SP_CTRL_REG,regval); }
int d2083_audio_enable_zcd(int enable) { int ret = 0; dlg_info("d2083_audio_enable_zcd =%d \n",enable); ret |= audio_set_bits(D2083_PREAMP_A_CTRL1_REG, D2083_PREAMP_ZC_EN); ret |= audio_set_bits(D2083_PREAMP_B_CTRL1_REG, D2083_PREAMP_ZC_EN); ret |= audio_set_bits(D2083_HP_L_CTRL_REG, D2083_HP_AMP_ZC_EN); ret |= audio_set_bits(D2083_HP_R_CTRL_REG, D2083_HP_AMP_ZC_EN); ret |= audio_set_bits(D2083_SP_NON_CLIP_ZC_REG, D2083_SP_ZC_EN); return ret; }
int d2083_core_reg2volt(int reg) { int volt = -EINVAL; int i; for (i = 0; i < ARRAY_SIZE(core_vol_list); i++) { if (core_vol_list[i][1] == reg) { volt = core_vol_list[i][0]; break; } } dlg_info("[DLG] [%s]-volt[%d]\n", __func__, volt); return volt; }
static int d2041_regulator_get_voltage(struct regulator_dev *rdev) { struct d2041 *d2041 = rdev_get_drvdata(rdev); unsigned int reg_num, regulator_id = rdev_get_id(rdev); int ret; u8 val; dlg_info("[[%s]], regulator_id[%d]\n", __func__, regulator_id); reg_num = get_regulator_reg(regulator_id); ret = d2041_reg_read(d2041, reg_num, &val); val &= D2041_MAX_VSEL; ret = mV_to_uV(d2041_regulator_val_to_mvolts(val, regulator_id, rdev)); return ret; }
int d2083_audio_set_input_preamp_gain(enum d2083_input_path_sel inpath_sel, enum d2083_preamp_gain_val pagain_val) { int reg; u8 regval; if (inpath_sel == D2083_INPUTA) reg = D2083_PREAMP_A_CTRL1_REG; else if (inpath_sel == D2083_INPUTB) reg = D2083_PREAMP_B_CTRL1_REG; else return -EINVAL; regval = audio_read(reg) & ~D2083_PREAMP_VOL; regval |= (pagain_val << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL; dlg_info("[%s]-addr[0x%x] ihfgain_val[0x%x]\n", __func__, reg,regval); return audio_write(reg,regval); }
// speaker on/off int d2083_audio_hs_ihf_poweron1(void) { int ret = 0; u8 regval; if(ihf_power_status == true) return ret; ihf_power_status = true; dlg_info("%s HP =%d \n",__func__, dlg_audio->HSenabled); // if(dlg_audio->HSenabled==false) // audio_write(D2083_LDO_AUD_MCTL_REG, 0x44); //AUD_LDO on audio_write(D2083_MXHPL_CTRL_REG,0x19); regval = audio_read(D2083_PREAMP_A_CTRL1_REG); regval = (regval | D2083_PREAMP_EN) & ~D2083_PREAMP_MUTE; ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval); ret |= audio_write(D2083_PREAMP_A_CTRL2_REG,0x03); //pre amp A fully differential regval = audio_read(D2083_SP_CTRL_REG); regval &= ~D2083_SP_MUTE; regval |= D2083_SP_EN; ret |= audio_write(D2083_SP_CTRL_REG,regval); ret |= audio_write(D2083_SP_CFG1_REG,0x00); ret |= audio_write(D2083_SP_CFG2_REG,0x00); //ret |= audio_write(D2083_SP_NG1_REG,0x0F); //ret |= audio_write(D2083_SP_NG2_REG,0x07); ret |= audio_write(D2083_SP_NON_CLIP_ZC_REG,0x00); ret |= audio_write(D2083_SP_NON_CLIP_REG,0x00); ret |= audio_write(D2083_SP_PWR_REG,0x00); ret |= audio_write(D2083_BIAS_CTRL_REG,0x3F); dlg_audio->IHFenabled = true; return ret; }
static int set_regulator_mctl_mode(struct d2041 *d2041, int regulator_id, u8 mode) { u8 reg_val, mctl_reg; int ret = 0; if(regulator_id < 0 || regulator_id >= D2041_NUMBER_OF_REGULATORS) return -EINVAL; if(mode > REGULATOR_MCTL_TURBO) return -EINVAL; mctl_reg = get_regulator_mctl_reg(regulator_id); ret = d2041_reg_read(d2041, mctl_reg, ®_val); if(ret < 0) return ret; reg_val &= ~(D2041_REGULATOR_MCTL0 | D2041_REGULATOR_MCTL2); reg_val |= ((mode << MCTL0_SHIFT) | ( mode << MCTL2_SHIFT)); ret = d2041_reg_write(d2041, mctl_reg, reg_val); dlg_info("[REGULATOR] %s. reg_val = 0x%X\n", __func__, reg_val); return ret; }
int d2083_audio_multicast(u8 flag) { u8 regval; int ret = 0; dlg_info("%s = %d\n",__func__, flag); switch(flag) { case DLG_REMOVE_IHF: if(!is_playback_stop) { ret = audio_write(D2083_MXHPL_CTRL_REG,0x07); regval = audio_read(D2083_PREAMP_B_CTRL1_REG); ret = audio_write(D2083_PREAMP_A_CTRL1_REG,regval); } ret |= d2083_audio_hs_ihf_poweroff(); break; case DLG_REMOVE_HS: ret = d2083_audio_hs_poweron1(0); break; case DLG_ADD_IHF: ret = audio_write(D2083_MXHPL_CTRL_REG,0x19); ret |= d2083_audio_hs_ihf_poweron1(); break; case DLG_ADD_HS: ret = d2083_audio_hs_poweron1(1); break; default: break; } return ret; }
static long d2083_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct d2083 *d2083 = file->private_data; pmu_reg reg; int ret = 0; u8 reg_val, event_reg[4]; if (!d2083) return -ENOTTY; // _kg TODO: Checking if d2083_reg_write() and d2083_reg_read() // return with success. switch (cmd) { case BCM_PMU_IOCTL_ENABLE_INTS: ret = d2083_block_read(d2083, D2083_EVENTA_REG, 4, event_reg); dlg_info("int register 0x%X = 0x%X\n", D2083_EVENTA_REG, event_reg[0]); dlg_info("int register 0x%X = 0x%X\n", D2083_EVENTB_REG, event_reg[1]); dlg_info("int register 0x%X = 0x%X\n", D2083_EVENTC_REG, event_reg[2]); dlg_info("int register 0x%X = 0x%X\n", D2083_EVENTD_REG, event_reg[3]); /* Clear all latched interrupts if any */ d2083_reg_write(d2083, D2083_EVENTA_REG, 0xFF); d2083_reg_write(d2083, D2083_EVENTB_REG, 0xFF); d2083_reg_write(d2083, D2083_EVENTC_REG, 0xFF); d2083_reg_write(d2083, D2083_EVENTD_REG, 0xFF); enable_irq(d2083->chip_irq); break; case BCM_PMU_IOCTL_DISABLE_INTS: disable_irq_nosync(d2083->chip_irq); break; case BCM_PMU_IOCTL_READ_REG: if (copy_from_user(®, (pmu_reg *)arg, sizeof(pmu_reg)) != 0) return -EFAULT; // DLG eric. 03/Nov/2011. Change prototype //reg.val = d2083_reg_read(d2083, reg.reg); // TODO: Check parameter. ®.val ret = d2083_reg_read(d2083, reg.reg, ®_val); reg.val = (unsigned short)reg_val; if (copy_to_user((pmu_reg *)arg, ®, sizeof(pmu_reg)) != 0) return -EFAULT; break; case BCM_PMU_IOCTL_WRITE_REG: if (copy_from_user(®, (pmu_reg *)arg, sizeof(pmu_reg)) != 0) return -EFAULT; d2083_reg_write(d2083, reg.reg, (u8)reg.val); break; #if 0 case BCM_PMU_IOCTL_SET_VOLTAGE: case BCM_PMU_IOCTL_GET_VOLTAGE: case BCM_PMU_IOCTL_GET_REGULATOR_STATE: case BCM_PMU_IOCTL_SET_REGULATOR_STATE: case BCM_PMU_IOCTL_ACTIVATESIM: case BCM_PMU_IOCTL_DEACTIVATESIM: ret = d2083_ioctl_regulator(d2083, cmd, arg); break; #endif case BCM_PMU_IOCTL_POWERONOFF: // d2083_set_bits(d2083,D2083_POWERCONT_REG,D2083_POWERCONT_RTCAUTOEN); d2083_shutdown(d2083); break; default: dlg_err("%s: unsupported cmd\n", __func__); ret = -ENOTTY; } return ret; }
static int d2083_dbg_parse_args(char *cmd, struct pmu_debug *dbg) { char *tok; /* used to separate tokens */ const char ct[] = " \t"; /* space or tab delimits the tokens */ bool count_flag = false; /* whether -c option is present or not */ int tok_count = 0; /* total number of tokens parsed */ int i = 0; dbg->len = 0; /* parse the input string */ while ((tok = strsep(&cmd, ct)) != NULL) { dlg_info("token: %s\n", tok); /* first token is always address */ if (tok_count == 0) { sscanf(tok, "%x", &dbg->addr); } else if (strnicmp(tok, "-c", 2) == 0) { /* the next token will be number of regs to read */ tok = strsep(&cmd, ct); if (tok == NULL) return -EINVAL; tok_count++; sscanf(tok, "%d", &dbg->len); count_flag = true; break; } else { int val; /* this is a value to be written to the pmu register */ sscanf(tok, "%x", &val); if (i < MAX_REGS_READ_WRITE) { dbg->val[i] = val; i++; } } tok_count++; } /* decide whether it is a read or write operation based on the * value of tok_count and count_flag. * tok_count = 0: no inputs, invalid case. * tok_count = 1: only reg address is given, so do a read. * tok_count > 1, count_flag = false: reg address and atleast one * value is present, so do a write operation. * tok_count > 1, count_flag = true: to a multiple reg read operation. */ switch (tok_count) { case 0: return -EINVAL; case 1: dbg->read_write = PMUDBG_READ_REG; dbg->len = 1; break; default: if (count_flag == true) { dbg->read_write = PMUDBG_READ_REG; } else { dbg->read_write = PMUDBG_WRITE_REG; dbg->len = i; } } return 0; }
int d2083_device_init(struct d2083 *d2083, int irq, struct d2083_platform_data *pdata) { int ret = 0;//, tmp; //struct regulator *regulator; #ifdef D2083_REG_DEBUG int i; u8 data; #endif if(d2083 != NULL) d2083_regl_info = d2083; else goto err; dlg_info("D2083 Driver version : %s\n", D2083_VERSION); d2083->pmic.max_dcdc = 25; // d2083->pdata = pdata; #if defined(CONFIG_KONA_PMU_BSC_HS_MODE) || defined(CONFIG_KONA_PMU_BSC_HS_1625KHZ) d2083_set_bits(d2083, D2083_CONTROLB_REG, D2083_CONTROLB_I2C_SPEED); /* Page write for I2C we donot support repeated write and I2C speed set to 1.7MHz */ d2083_clear_bits(d2083, D2083_CONTROLB_REG, D2083_CONTROLB_WRITEMODE); #else /* Page write for I2C we donot support repeated write and I2C speed set to 400KHz */ d2083_clear_bits(d2083, D2083_CONTROLB_REG, D2083_CONTROLB_WRITEMODE | D2083_CONTROLB_I2C_SPEED); #endif #if 0 // TEST ONLY { // register dump int i=0; u8 reg_val; for(i=0; i<=D2083_BIAS_CTRL_REG; i++) { d2083_reg_read(d2083, i, ®_val); printk(KERN_ERR "addr[0x%x] = [0x%x]\n", i, reg_val); } } #endif d2083_reg_write(d2083, D2083_BUCKA_REG,0x9A); #if 1 // 20120221 LDO13 issue d2083_reg_write(d2083, D2083_PDDIS_REG,0x0); d2083_reg_write(d2083, D2083_PULLDOWN_REG_D,0x0); // audio d2083_reg_write(d2083, D2083_PREAMP_A_CTRL1_REG,0x34); d2083_reg_write(d2083, D2083_PREAMP_A_CTRL2_REG,0x0); d2083_reg_write(d2083, D2083_SP_CTRL_REG,0xCC); // LDO d2083_reg_write(d2083, D2083_LDO1_REG, 0x00); //LDO 1 1.2V // spare d2083_reg_write(d2083, D2083_LDO3_REG, 0x24); //LDO 3 3.0V // VDD_SENSOR_3.0V d2083_reg_write(d2083, D2083_LDO6_REG, 0x20); //LDO 6 2.8V // VCAM_A_2.8V d2083_reg_write(d2083, D2083_LDO7_REG, 0x2A); //LDO 7 3.3V // VDD_VIB_3.3V d2083_reg_write(d2083, D2083_LDO8_REG, 0x64); //LDO 8 3.0V // VLCD_3.0V d2083_reg_write(d2083, D2083_LDO9_REG, 0x24); //LDO 9 3.0V // VDD_SDXC d2083_reg_write(d2083, D2083_LDO11_REG, 0x24); //LDO 11 3.0V // VSIM1_3.0V d2083_reg_write(d2083, D2083_LDO13_REG, 0x24); //LDO 13 3.0V // VDD_SDIO_3.0V d2083_reg_write(d2083, D2083_LDO14_REG, 0xC ); //LDO 14 1.8V // VTOUCH_1.8V d2083_reg_write(d2083, D2083_LDO15_REG, 0x2A); //LDO 15 3.3V // VTOUCH_3.3V d2083_reg_write(d2083, D2083_LDO16_REG, 0xC ); //LDO 16 1.8V // VCAMC_IO_1.8V d2083_reg_write(d2083, D2083_LDO17_REG, 0x20); //LDO 17 2.8V // VCAM_AF_2.8V d2083_reg_write(d2083, D2083_BUCK4_REG, 0x54); //BUCK 4 3.3V // VDD_3G_PAM_3.3V #endif d2083_reg_write(d2083,D2083_BBATCONT_REG,0x1F); d2083_set_bits(d2083,D2083_SUPPLY_REG,D2083_SUPPLY_BBCHGEN); /* DLG todo */ if (pdata && pdata->irq_init) { dlg_crit("\nD2083-core.c: IRQ PIN Configuration \n"); ret = pdata->irq_init(d2083); if (ret != 0) { dev_err(d2083->dev, "Platform init() failed: %d\n", ret); goto err_irq; } } d2083_dev_info = d2083; pm_power_off = d2083_system_poweroff; ret = d2083_irq_init(d2083, irq, pdata); if (ret < 0) goto err; //DLG todo d2083_worker_init(irq); //new for Samsung if (pdata && pdata->init) { ret = pdata->init(d2083); if (ret != 0) { dev_err(d2083->dev, "Platform init() failed: %d\n", ret); goto err_irq; } } // Regulator Specific Init ret = d2083_platform_regulator_init(d2083); if (ret != 0) { dev_err(d2083->dev, "Platform Regulator init() failed: %d\n", ret); goto err_irq; } d2083_client_dev_register(d2083, "d2083-battery", &(d2083->batt.pdev)); d2083_client_dev_register(d2083, "d2083-rtc", &(d2083->rtc.pdev)); d2083_client_dev_register(d2083, "d2083-onkey", &(d2083->onkey.pdev)); d2083_client_dev_register(d2083, "d2083-audio", &(d2083->audio.pdev)); d2083_system_event_init(d2083); #if defined(CONFIG_MACH_RHEA_SS_IVORY) || defined(CONFIG_MACH_RHEA_SS_NEVIS) || defined(CONFIG_MACH_RHEA_SS_NEVISP) d2083_debug_proc_init(d2083); #endif /* CONFIG_MACH_RHEA_SS_IVORY */ #ifdef D2083_REG_DEBUG for(i=0; i<D2083_MAX_REGISTER_CNT; i++) { d2083_reg_read(d2083, i, &data); d2083_write_reg_cache(i,data); } #endif // temporary code if (pdata->pmu_event_cb) pdata->pmu_event_cb(0, 0); //PMU_EVENT_INIT_PLATFORM // set MCTRL_EN enabled set_MCTL_enabled(); return 0; err_irq: d2083_irq_exit(d2083); d2083_dev_info = NULL; pm_power_off = NULL; err: dlg_crit("\n\nD2083-core.c: device init failed ! \n\n"); return ret; }
int d2041_ioctl_regulator(struct d2041 *d2041, unsigned int cmd, unsigned long arg) { //struct max8986_regl_priv *regl_priv = (struct max8986_regl_priv *) pri_data; int ret = -EINVAL; int regid; dlg_info("Inside %s, IOCTL command is %d\n", __func__, cmd); switch (cmd) { case BCM_PMU_IOCTL_SET_VOLTAGE: { pmu_regl_volt regulator; if (copy_from_user(®ulator, (pmu_regl_volt *)arg, sizeof(pmu_regl_volt)) != 0) { return -EFAULT; } if (regulator.regl_id < 0 || regulator.regl_id >= ARRAY_SIZE(d2041->pdata->regl_map)) return -EINVAL; regid = d2041->pdata->regl_map[regulator.regl_id].reg_id; if (regid < 0) return -EINVAL; ret = d2041_regulator_set_voltage(d2041_rdev[regid], regulator.voltage, regulator.voltage); break; } case BCM_PMU_IOCTL_GET_VOLTAGE: { pmu_regl_volt regulator; int volt; if (copy_from_user(®ulator, (pmu_regl_volt *)arg, sizeof(pmu_regl_volt)) != 0) { return -EFAULT; } if (regulator.regl_id < 0 || regulator.regl_id >= ARRAY_SIZE(d2041->pdata->regl_map)) return -EINVAL; regid = d2041->pdata->regl_map[regulator.regl_id].reg_id; if (regid < 0) return -EINVAL; volt = d2041_regulator_get_voltage(d2041_rdev[regid]); if (volt > 0) { regulator.voltage = volt; ret = copy_to_user((pmu_regl_volt *)arg, ®ulator, sizeof(regulator)); } else { ret = volt; } break; } case BCM_PMU_IOCTL_GET_REGULATOR_STATE: { pmu_regl rmode; unsigned int mode; if (copy_from_user(&rmode, (pmu_regl *)arg, sizeof(pmu_regl)) != 0) return -EFAULT; if (rmode.regl_id < 0 || rmode.regl_id >= ARRAY_SIZE(d2041->pdata->regl_map)) return -EINVAL; regid = d2041->pdata->regl_map[rmode.regl_id].reg_id; if (regid < 0) return -EINVAL; mode = d2041_regulator_get_mode(d2041_rdev[regid]); switch (mode) { case REGULATOR_MODE_FAST: rmode.state = PMU_REGL_TURBO; break; case REGULATOR_MODE_NORMAL: rmode.state = PMU_REGL_ON; break; case REGULATOR_MODE_STANDBY: rmode.state = PMU_REGL_ECO; break; default: rmode.state = PMU_REGL_OFF; break; }; ret = copy_to_user((pmu_regl *)arg, &rmode, sizeof(rmode)); break; } case BCM_PMU_IOCTL_SET_REGULATOR_STATE: { pmu_regl rmode; unsigned int mode; if (copy_from_user(&rmode, (pmu_regl *)arg, sizeof(pmu_regl)) != 0) return -EFAULT; if (rmode.regl_id < 0 || rmode.regl_id >= ARRAY_SIZE(d2041->pdata->regl_map)) return -EINVAL; regid = d2041->pdata->regl_map[rmode.regl_id].reg_id; if (regid < 0) return -EINVAL; switch (rmode.state) { case PMU_REGL_TURBO: mode = REGULATOR_MODE_FAST; break; case PMU_REGL_ON: mode = REGULATOR_MODE_NORMAL; break; case PMU_REGL_ECO: mode = REGULATOR_MODE_STANDBY; break; default: mode = REGULATOR_MCTL_OFF; break; }; ret = d2041_regulator_set_mode(d2041_rdev[regid], mode); break; } case BCM_PMU_IOCTL_ACTIVATESIM: { int id = 16; /*check the status of SIMLDO*/ pmu_sim_volt sim_volt; int value; if (copy_from_user(&sim_volt, (int *)arg, sizeof(int)) != 0) return -EFAULT; regid = d2041->pdata->regl_map[id].reg_id; if (regid < 0) return -EINVAL; /*check the status of SIMLDO*/ ret = d2041_regulator_is_enabled(d2041_rdev[regid]); if (ret) { dlg_info("SIMLDO is activated already\n"); return -EPERM; } /* Put SIMLDO in ON State */ ret = d2041_regulator_enable(d2041_rdev[regid]); if (ret) return ret; /* Set SIMLDO voltage */ value = 2500000; // 2.5V ret = d2041_regulator_set_voltage(d2041_rdev[regid], value, value); break; } case BCM_PMU_IOCTL_DEACTIVATESIM: { int id = 16; /*check the status of SIMLDO*/ ret = d2041_regulator_is_enabled(d2041_rdev[id]); if (!ret) { dlg_info("SIMLDFO is already disabled\n"); return -EPERM; } regid = d2041->pdata->regl_map[id].reg_id; if (regid < 0) return -EINVAL; ret = d2041_regulator_disable(d2041_rdev[regid]); if (ret) return ret; break; } } /*end of switch*/ return ret; }
int d2083_audio_hs_poweron1(bool on) { int ret = 0; u8 regval; //dlg_info("%s status:%d, cmd:%d\n",__func__,hs_pw_status, on); if ( hs_pw_status == on){ return ret; } hs_pw_status = on; dlg_info("%s HP=%d speaker_power=%d \n",__func__,on,dlg_audio->IHFenabled); if(on) { //if(dlg_audio->IHFenabled==false) //{ //audio_write(D2083_LDO_AUD_MCTL_REG, 0x44); //AUD_LDO on //audio_write(D2083_LDO1_MCTL_REG, 0x54); //mdelay(20); //} if (!dlg_audio_sleep) { ret |= audio_write(D2083_HP_L_CTRL_REG,0xF0); ret |= audio_write(D2083_HP_R_CTRL_REG,0xF0); ret = audio_write(D2083_HP_L_GAIN_REG,0x00); ret = audio_write(D2083_HP_R_GAIN_REG,0x00); ret = audio_write(D2083_HP_NG1_REG,0x10); msleep(30); // will test for pop noise newly } //dlg_audio->hs_pga_gain -= (LIMITED_SWAP_PRE - dlg_audio->hs_pre_gain-1); //dlg_audio->hs_pre_gain += (LIMITED_SWAP_PRE - dlg_audio->hs_pre_gain); #ifndef USE_AUDIO_DIFFERENTIAL regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL; regval |= ((dlg_audio->hs_pre_gain << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL); regval |= (D2083_PREAMP_EN | D2083_PREAMP_ZC_EN); regval &= ~D2083_PREAMP_MUTE; ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval); ret |= audio_write(D2083_PREAMP_B_CTRL2_REG,0x00); ret |= audio_write(D2083_MXHPR_CTRL_REG,0x11); ret |= audio_write(D2083_MXHPL_CTRL_REG,0x09); #else regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL; regval |= ((dlg_audio->hs_pre_gain << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL); regval |= (D2083_PREAMP_EN | D2083_PREAMP_ZC_EN); regval &= ~D2083_PREAMP_MUTE; ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval); ret |= audio_write(D2083_PREAMP_B_CTRL2_REG,0x03); if(dlg_audio->IHFenabled == false) { regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL; regval |= ((dlg_audio->hs_pre_gain << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL); regval |= (D2083_PREAMP_EN | D2083_PREAMP_ZC_EN); regval &= ~D2083_PREAMP_MUTE; ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval); ret |= audio_write(D2083_PREAMP_A_CTRL2_REG,0x03); } // HP Mixer controll if(dlg_audio->IHFenabled == false){ audio_write(D2083_MXHPL_CTRL_REG,0x07); } else { audio_write(D2083_MXHPL_CTRL_REG,0x19); } audio_write(D2083_MXHPR_CTRL_REG,0x19); #endif regval = audio_read(D2083_HP_L_GAIN_REG) & ~D2042_HP_AMP_GAIN & ~D2083_HP_AMP_MUTE_EN; ret |= audio_write(D2083_HP_L_GAIN_REG, regval | (dlg_audio->hs_pga_gain & D2042_HP_AMP_GAIN)); regval = audio_read(D2083_HP_R_GAIN_REG) & ~D2042_HP_AMP_GAIN & ~D2083_HP_AMP_MUTE_EN; ret |= audio_write(D2083_HP_R_GAIN_REG, regval | (dlg_audio->hs_pga_gain & D2042_HP_AMP_GAIN)); ret |= audio_write(D2083_CP_CTRL_REG,0xC9); ret |= audio_write(D2083_CP_DELAY_REG,0x85); ret |= audio_write(D2083_CP_DETECTOR_REG,0x00); ret |= audio_write(D2083_CP_VOL_THRESHOLD_REG,0x32); ret |= audio_write(D2083_BIAS_CTRL_REG,0x3F); msleep(65); #ifndef USE_AUDIO_DIFFERENTIAL regval = audio_read(D2083_PREAMP_B_CTRL1_REG); regval &= ~D2083_PREAMP_ZC_EN; ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval); #else regval = audio_read(D2083_PREAMP_B_CTRL1_REG); regval &= ~D2083_PREAMP_ZC_EN; ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval); if(dlg_audio->IHFenabled == false){ regval = audio_read(D2083_PREAMP_A_CTRL1_REG); regval &= ~D2083_PREAMP_ZC_EN; ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval); } #endif ret = audio_write(D2083_HP_NG1_REG, dlg_set_ng1); ret = audio_write(D2083_HP_NG2_REG, dlg_set_ng2); ret |= audio_write(D2083_HP_L_CTRL_REG,0xa0); ret |= audio_write(D2083_HP_R_CTRL_REG,0xa0); msleep(25); ret |= audio_write(D2083_CP_CTRL_REG,0xCD); msleep(40); dlg_audio->HSenabled = true; } else { #ifndef USE_AUDIO_DIFFERENTIAL regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL; regval |= (D2083_PREAMP_MUTE); ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval); #else regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL; regval |= (D2083_PREAMP_MUTE); ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval); if(dlg_audio->IHFenabled != true) { regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL; regval |= (D2083_PREAMP_MUTE); ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval); } #endif ret = audio_write(D2083_HP_L_GAIN_REG, dlg_audio->hs_pga_gain -2); ret = audio_write(D2083_HP_R_GAIN_REG, dlg_audio->hs_pga_gain -2); msleep(10); ret = audio_write(D2083_HP_L_GAIN_REG, dlg_audio->hs_pga_gain -5); ret = audio_write(D2083_HP_R_GAIN_REG, dlg_audio->hs_pga_gain -5); msleep(10); ret = audio_write(D2083_HP_L_GAIN_REG, dlg_audio->hs_pga_gain -10); ret = audio_write(D2083_HP_R_GAIN_REG, dlg_audio->hs_pga_gain -10); msleep(10); ret = audio_write(D2083_HP_NG1_REG,0x11); ret = audio_write(D2083_HP_NG2_REG,0x07); if(dlg_audio->IHFenabled != true) msleep(50); ret = audio_write(D2083_HP_L_GAIN_REG,0x00); ret = audio_write(D2083_HP_R_GAIN_REG,0x00); msleep(10); audio_write(D2083_CP_CTRL_REG,0xC9); dlg_audio_sleep = false; dlg_audio->HSenabled = false; // if(dlg_audio->IHFenabled==false) { // audio_write(D2083_LDO_AUD_MCTL_REG, 0x00); //AUD_LDO off // audio_write(D2083_LDO1_MCTL_REG, 0x54); // } } return ret; }
static int d2083_ioctl_open(struct inode *inode, struct file *file) { dlg_info("%s\n", __func__); file->private_data = PDE(inode)->data; return 0; }