int da9052_read_tjunc(struct da9052 *da9052, char *buf) { struct da9052_ssc_msg msg; unsigned char temp; int ret; msg.addr = DA9052_TJUNCRES_REG; msg.data = 0; da9052_lock(da9052); ret = da9052->read(da9052, &msg); if (ret) goto err_ssc_comm; temp = msg.data; msg.addr = DA9052_TOFFSET_REG; msg.data = 0; ret = da9052->read(da9052, &msg); if (ret) goto err_ssc_comm; da9052_unlock(da9052); /* Calculate Junction temperature */ temp = (temp - msg.data); *buf = temp; return 0; err_ssc_comm: da9052_unlock(da9052); return -EIO; }
static void da9052_onkey_work_func(struct work_struct *work) { struct da9052_onkey_data *da9052_onkey = container_of(work, struct da9052_onkey_data, polling_work.work); struct da9052_ssc_msg msg; unsigned int ret; int value; da9052_lock(da9052_onkey->da9052); msg.addr = DA9052_STATUSA_REG; ret = da9052_onkey->da9052->read(da9052_onkey->da9052, &msg); if (ret) { da9052_unlock(da9052_onkey->da9052); return; } da9052_unlock(da9052_onkey->da9052); value = (msg.data & DA9052_STATUSA_NONKEY) ? 0 : 1; input_report_key(da9052_onkey->input, KEY_POWER, value); input_sync(da9052_onkey->input); #ifdef CONFIG_CCIMX5X_PM_POWER_BUTTON da9052_power_button( da9052_onkey->da9052 , value ); #endif /* if key down, polling for up */ if (value) schedule_delayed_work(&da9052_onkey->polling_work, HZ/10); }
static int da9052_stop_adc(struct da9052 *da9052, unsigned channel) { int ret; struct da9052_ssc_msg msg; msg.addr = DA9052_ADCCONT_REG; msg.data = 0; da9052_lock(da9052); ret = da9052->read(da9052, &msg); if (ret != 0) goto err_ssc_comm; if (channel == DA9052_ADC_VDDOUT) msg.data = (msg.data & ~(DA9052_ADCCONT_AUTOVDDEN)); else if (channel == DA9052_ADC_ADCIN4) msg.data = (msg.data & ~(DA9052_ADCCONT_AUTOAD4EN)); else if (channel == DA9052_ADC_ADCIN5) msg.data = (msg.data & ~(DA9052_ADCCONT_AUTOAD5EN)); else if (channel == DA9052_ADC_ADCIN6) msg.data = (msg.data & ~(DA9052_ADCCONT_AUTOAD6EN)); else return -EINVAL; ret = da9052->write(da9052, &msg); if (ret != 0) goto err_ssc_comm; da9052_unlock(da9052); return 0; err_ssc_comm: da9052_unlock(da9052); return -EIO; }
int da9052_ldo_buck_disable(struct regulator_dev *rdev) { struct da9052_regulator_priv *priv = rdev_get_drvdata(rdev); int id = rdev_get_id(rdev); int ret; struct da9052_ssc_msg ssc_msg; ssc_msg.addr = da9052_regulators[id].reg_add; ssc_msg.data = 0; da9052_lock(priv->da9052); ret = priv->da9052->read(priv->da9052, &ssc_msg); if (ret) { da9052_unlock(priv->da9052); return -EIO; } ssc_msg.data = (ssc_msg.data & ~(da9052_regulators[id].en_bit_mask)); ret = priv->da9052->write(priv->da9052, &ssc_msg); if (ret) { da9052_unlock(priv->da9052); return -EIO; } da9052_unlock(priv->da9052); return 0; }
int da9052_read_tbat_ich(struct da9052 *da9052, char *data, int channel_no) { struct da9052_ssc_msg msg; int ret; /* Read TBAT conversion result */ switch (channel_no) { case DA9052_ADC_TBAT: msg.addr = DA9052_TBATRES_REG; break; case DA9052_ADC_ICH: msg.addr = DA9052_ICHGAV_REG; break; default: return -EINVAL; } msg.data = 0; da9052_lock(da9052); ret = da9052->read(da9052, &msg); if (ret) goto err_ssc_comm; da9052_unlock(da9052); *data = msg.data; printk(KERN_INFO"msg.data 1= %d\n", msg.data); msg.data = 28; da9052_lock(da9052); ret = da9052->write(da9052, &msg); if (ret) goto err_ssc_comm; da9052_unlock(da9052); printk(KERN_INFO"msg.data2 = %d\n", msg.data); msg.data = 0; da9052_lock(da9052); ret = da9052->read(da9052, &msg); if (ret) goto err_ssc_comm; da9052_unlock(da9052); printk(KERN_INFO"msg.data3 = %d\n", msg.data); return 0; err_ssc_comm: da9052_unlock(da9052); return ret; }
static int da9052_set_suspend_voltage(struct regulator_dev *rdev, int uV) { struct da9052_regulator_priv *priv = rdev_get_drvdata(rdev); struct da9052_ssc_msg ssc_msg; int id = rdev_get_id(rdev); int ret; int ldo_volt = 0; /* Check Minimum/ Maximum voltage range */ if (uV < da9052_regulators[id].reg_const.min_uV || uV > da9052_regulators[id].reg_const.max_uV) return -EINVAL; /* Get the ldo register value */ /* Varying step size for BUCK PERI */ if ((da9052_regulators[id].reg_desc.id == DA9052_BUCK_PERI) && (uV >= DA9052_BUCK_PERI_VALUES_3000)) { ldo_volt = (DA9052_BUCK_PERI_VALUES_3000 - da9052_regulators[id].reg_const.min_uV)/ (da9052_regulators[id].step_uV); ldo_volt += (uV - DA9052_BUCK_PERI_VALUES_3000)/ (DA9052_BUCK_PERI_STEP_ABOVE_3000); } else{ ldo_volt = (uV - da9052_regulators[id].reg_const.min_uV)/ (da9052_regulators[id].step_uV); } ldo_volt |= 0x80; dev_info(&rdev->dev, "preset to %d %x\n", uV, ldo_volt); /* Configure LDO Voltage, CONF bits */ ssc_msg.addr = da9052_regulators[id].reg_add; ssc_msg.data = 0; /* Read register */ da9052_lock(priv->da9052); ret = priv->da9052->read(priv->da9052, &ssc_msg); if (ret) { da9052_unlock(priv->da9052); return -EIO; } ssc_msg.data = (ssc_msg.data & ~(da9052_regulators[id].mask_bits)); ssc_msg.data |= ldo_volt; ret = priv->da9052->write(priv->da9052, &ssc_msg); if (ret) { da9052_unlock(priv->da9052); return -EIO; } da9052_unlock(priv->da9052); return 0; }
static ssize_t da9052_adc_read_start_stop(struct device *dev, struct device_attribute *devattr, char *buf) { struct platform_device *pdev = to_platform_device(dev); struct da9052_adc_priv *priv = platform_get_drvdata(pdev); struct da9052_ssc_msg msg; int channel = to_sensor_dev_attr(devattr)->index; int ret; ret = da9052_start_adc(priv->da9052, channel); if (ret < 0) return ret; /* Read the ADC converted value */ switch (channel) { case DA9052_ADC_VDDOUT: msg.addr = DA9052_VDDRES_REG; break; #if (DA9052_ADC_CONF_ADC4 == 1) case DA9052_ADC_ADCIN4: msg.addr = DA9052_ADCIN4RES_REG; break; #endif #if (DA9052_ADC_CONF_ADC5 == 1) case DA9052_ADC_ADCIN5: msg.addr = DA9052_ADCIN5RES_REG; break; #endif #if (DA9052_ADC_CONF_ADC6 == 1) case DA9052_ADC_ADCIN6: msg.addr = DA9052_ADCIN6RES_REG; break; #endif default: return -EINVAL; } msg.data = 0; da9052_lock(priv->da9052); ret = priv->da9052->read(priv->da9052, &msg); if (ret != 0) goto err_ssc_comm; da9052_unlock(priv->da9052); ret = da9052_stop_adc(priv->da9052, channel); if (ret < 0) return ret; return sprintf(buf, "%u\n", msg.data); err_ssc_comm: da9052_unlock(priv->da9052); return ret; }
static void da9052_power_button( struct da9052 *da9052 , int value ) { struct da9052_ssc_msg ssc_msg; unsigned int ret; if( system_state != SYSTEM_RUNNING) return; switch (pwron_state){ case PWRON_FROM_RESUME: // Are we waking up from a non power button suspend // and this is the falling edge already? if( !value ) pwron_state = PWRON_FROM_RESUME; else // Skipping falling edge pwron_state = PWRON_FALLING_EDGE; break; case PWRON_FALLING_EDGE: // Suspend on rising edge pm_suspend(PM_SUSPEND_MEM); // Did we wake by a power button press? da9052_lock(da9052); ssc_msg.addr = DA9052_EVENTB_REG; ret = da9052->read(da9052, &ssc_msg); if (ret) { da9052_unlock(da9052); pwron_state = PWRON_FROM_RESUME; return; } da9052_unlock(da9052); if( ssc_msg.data | DA9052_EVENTB_ENONKEY ) pwron_state = PWRON_FROM_SUSPEND; else // Waken by other source pwron_state = PWRON_FROM_RESUME; break; case PWRON_FROM_SUSPEND: // Ignoring raising edge pwron_state = PWRON_FROM_RESUME; break; default: pr_err("power_on_evt_handler: Unitialized state\n"); } }
int da9052_ldo_buck_get_voltage(struct regulator_dev *rdev) { struct da9052_regulator_priv *priv = rdev_get_drvdata(rdev); struct da9052_ssc_msg ssc_msg; int id = rdev_get_id(rdev); int ldo_volt = 0; int ldo_volt_uV = 0; int ret; ssc_msg.addr = da9052_regulators[id].reg_add; ssc_msg.data = 0; /* Read register */ da9052_lock(priv->da9052); ret = priv->da9052->read(priv->da9052, &ssc_msg); if (ret) { da9052_unlock(priv->da9052); return -EIO; } da9052_unlock(priv->da9052); ldo_volt = ssc_msg.data & da9052_regulators[id].mask_bits; if (da9052_regulators[id].reg_desc.id == DA9052_BUCK_PERI) { if (ldo_volt >= DA9052_BUCK_PERI_VALUES_UPTO_3000) { ldo_volt_uV = ((DA9052_BUCK_PERI_VALUES_UPTO_3000 * da9052_regulators[id].step_uV) + da9052_regulators[id].reg_const.min_uV); ldo_volt_uV = (ldo_volt_uV + (ldo_volt - DA9052_BUCK_PERI_VALUES_UPTO_3000) * (DA9052_BUCK_PERI_STEP_ABOVE_3000)); } else { ldo_volt_uV = (ldo_volt * da9052_regulators[id].step_uV) + da9052_regulators[id].reg_const.min_uV; } } else { ldo_volt_uV = (ldo_volt * da9052_regulators[id].step_uV) + da9052_regulators[id].reg_const.min_uV; } return ldo_volt_uV; }
static int da9052_backlight_brightness_set(struct da9052_backlight_data *data, int brightness, enum da9052_led_number led) { /* * Mechanism for brightness control: * For brightness control, current is used. * PWM feature is not used. * To use PWM feature, a fixed value of current should be defined. */ int ret = 0; unsigned int led_ramp_bit; unsigned int led_current_register; unsigned int led_current_sink_bit; unsigned int led_boost_en_bit; struct da9052_ssc_msg msg; switch (led) { case LED1: led_ramp_bit = DA9052_LEDCONT_LED1RAMP; led_current_register = DA9052_LED1CONF_REG; led_current_sink_bit = DA9052_LEDCONT_LED1EN; led_boost_en_bit = DA9052_BOOST_LED1INEN; break; case LED2: led_ramp_bit = DA9052_LEDCONT_LED2RAMP; led_current_register = DA9052_LED2CONF_REG; led_current_sink_bit = DA9052_LEDCONT_LED2EN; led_boost_en_bit = DA9052_BOOST_LED2INEN; break; case LED3: led_ramp_bit = DA9052_LEDCONT_LED3RAMP; led_current_register = DA9052_LED3CONF_REG; led_current_sink_bit = DA9052_LEDCONT_LED3EN; led_boost_en_bit = DA9052_BOOST_LED3INEN; break; default: return -EIO; } /* * 3 registers to be written * 1. LED current for brightness * 2. LED enable/disable depending on the brightness * 3. BOOST enable/disable depending on the brightness */ /* Configure LED current i.e. brightness */ msg.addr = led_current_register; msg.data = brightness; /* Write to the DA9052 register */ da9052_lock(data->da9052); ret = data->da9052->write(data->da9052, &msg); if (ret) { da9052_unlock(data->da9052); return ret; } da9052_unlock(data->da9052); /* * Check if brightness = 0 * and decide if led to be disabled */ msg.addr = DA9052_LEDCONT_REG; msg.data = 0; /* Read LED_CONT register */ da9052_lock(data->da9052); ret = data->da9052->read(data->da9052, &msg); if (ret) { da9052_unlock(data->da9052); return ret; } da9052_unlock(data->da9052); /* Set/Clear the LED current sink bit */ msg.data = brightness ? (msg.data | led_current_sink_bit) : (msg.data & ~(led_current_sink_bit)); /* Disable current ramping */ msg.data = (msg.data & ~(led_ramp_bit)); /* Write to the DA9052 register */ da9052_lock(data->da9052); ret = data->da9052->write(data->da9052, &msg); if (ret) { da9052_unlock(data->da9052); return ret; } da9052_unlock(data->da9052); /* Configure BOOST */ msg.addr = DA9052_BOOST_REG; msg.data = 0; /* Read LED_CONT register */ da9052_lock(data->da9052); ret = data->da9052->read(data->da9052, &msg); if (ret) { da9052_unlock(data->da9052); return ret; } da9052_unlock(data->da9052); /* Set/Clear the LED BOOST enable bit */ msg.data = brightness ? (msg.data | led_boost_en_bit) : (msg.data & ~(led_boost_en_bit)); /* Set/Clear the BOOST converter enable bit */ if (0 == (data->is_led1_present | data->is_led2_present | data->is_led3_present)) { msg.data = msg.data & ~(DA9052_BOOST_BOOSTEN); } else msg.data = (msg.data | DA9052_BOOST_BOOSTEN); /* Write to the DA9052 register */ da9052_lock(data->da9052); ret = data->da9052->write(data->da9052, &msg); if (ret) { da9052_unlock(data->da9052); return ret; } da9052_unlock(data->da9052); return 0; }
static int __devinit da9052_onkey_probe(struct platform_device *pdev) { struct da9052_onkey_data *da9052_onkey; int error,ret; struct da9052_ssc_msg msg; da9052_onkey = kzalloc(sizeof(*da9052_onkey), GFP_KERNEL); da9052_onkey->input = input_allocate_device(); if (!da9052_onkey->input) { dev_err(&pdev->dev, "failed to allocate data device\n"); error = -ENOMEM; goto fail1; } da9052_onkey->da9052 = dev_get_drvdata(pdev->dev.parent); if (!da9052_onkey->input) { dev_err(&pdev->dev, "failed to allocate input device\n"); error = -ENOMEM; goto fail2; } da9052_onkey->input->evbit[0] = BIT_MASK(EV_KEY); da9052_onkey->input->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER); da9052_onkey->input->name = "da9052-onkey"; da9052_onkey->input->phys = "da9052-onkey/input0"; da9052_onkey->input->dev.parent = &pdev->dev; INIT_DELAYED_WORK(&da9052_onkey->polling_work, da9052_onkey_work_func); /* Set the EH structure */ da9052_onkey->eh_data.eve_type = ONKEY_EVE; da9052_onkey->eh_data.call_back = &da9052_onkey_report_event; error = da9052_onkey->da9052->register_event_notifier( da9052_onkey->da9052, &da9052_onkey->eh_data); if (error) goto fail2; error = input_register_device(da9052_onkey->input); if (error) { dev_err(&pdev->dev, "Unable to register input\ device,error: %d\n", error); goto fail3; } platform_set_drvdata(pdev, da9052_onkey); // Unmask IRQ da9052_lock(da9052_onkey->da9052); msg.addr = DA9052_IRQMASKB_REG; ret = da9052_onkey->da9052->read(da9052_onkey->da9052, &msg); if (ret) { da9052_unlock(da9052_onkey->da9052); return 0; } msg.data &= ~DA9052_IRQMASKB_MNONKEY; da9052_onkey->da9052->write(da9052_onkey->da9052, &msg); da9052_unlock(da9052_onkey->da9052); return 0; fail3: da9052_onkey->da9052->unregister_event_notifier(da9052_onkey->da9052, &da9052_onkey->eh_data); fail2: input_free_device(da9052_onkey->input); fail1: kfree(da9052_onkey); return error; }
int da9052_manual_read(struct da9052 *da9052, unsigned char channel) { unsigned char man_timeout_cnt = DA9052_ADC_MAX_MANCONV_RETRY_COUNT; struct da9052_ssc_msg msg; unsigned short calc_data; unsigned int ret; u16 data = 0; msg.addr = DA9052_ADCMAN_REG; msg.data = channel; msg.data = (msg.data | DA9052_ADCMAN_MANCONV); mutex_lock(&da9052->manconv_lock); da9052_lock(da9052); ret = da9052->write(da9052, &msg); if (ret) goto err_ssc_comm; da9052_unlock(da9052); /* Wait for the event */ do { msg.addr = DA9052_ADCCONT_REG; msg.data = 0; da9052_lock(da9052); ret = da9052->read(da9052, &msg); if (ret) goto err_ssc_comm; da9052_unlock(da9052); if (DA9052_ADCCONT_ADCMODE & msg.data) msleep(1); else msleep(10); msg.addr = DA9052_ADCMAN_REG; msg.data = 0; da9052_lock(da9052); ret = da9052->read(da9052, &msg); if (ret) goto err_ssc_comm; da9052_unlock(da9052); /* Counter to avoid endless while loop */ man_timeout_cnt--; if (man_timeout_cnt == 1) { if (!(msg.data & DA9052_ADCMAN_MANCONV)) break; else goto err_ssc_comm; } /* Wait until the MAN_CONV bit is cleared to zero */ } while (msg.data & DA9052_ADCMAN_MANCONV); msg.addr = DA9052_ADCRESH_REG; msg.data = 0; da9052_lock(da9052); ret = da9052->read(da9052, &msg); if (ret) goto err_ssc_comm; da9052_unlock(da9052); calc_data = (unsigned short)msg.data; data = (calc_data << 2); msg.addr = DA9052_ADCRESL_REG; msg.data = 0; da9052_lock(da9052); ret = da9052->read(da9052, &msg); if (ret) goto err_ssc_comm; da9052_unlock(da9052); /* Clear first 14 bits before ORing */ calc_data = (unsigned short)msg.data & 0x0003; data |= calc_data; mutex_unlock(&da9052->manconv_lock); return data; err_ssc_comm: mutex_unlock(&da9052->manconv_lock); da9052_unlock(da9052); return -EIO; }
static int da9052_adc_hw_init(struct da9052 *da9052) { struct da9052_ssc_msg msg; int ret; /* ADC channel 4 and 5 are by default enabled */ #if (DA9052_ADC_CONF_ADC4 == 1) msg.addr = DA9052_GPIO0001_REG; msg.data = 0; da9052_lock(da9052); ret = da9052->read(da9052, &msg); if (ret) goto err_ssc_comm; msg.data = (msg.data & ~(DA9052_GPIO0001_GPIO0PIN)); ret = da9052->write(da9052, &msg); if (ret != 0) goto err_ssc_comm; da9052_unlock(da9052); #endif #if (DA9052_ADC_CONF_ADC5 == 1) msg.addr = DA9052_GPIO0001_REG; msg.data = 0; da9052_lock(da9052); ret = da9052->read(da9052, &msg); if (ret) goto err_ssc_comm; msg.data = (msg.data & ~(DA9052_GPIO0001_GPIO0PIN)); ret = da9052->write(da9052, &msg); if (ret != 0) goto err_ssc_comm; da9052_unlock(da9052); #endif #if (DA9052_ADC_CONF_ADC6 == 1) msg.addr = DA9052_GPIO0203_REG; msg.data = 0; da9052_lock(da9052); ret = da9052->read(da9052, &msg); if (ret) goto err_ssc_comm; msg.data = (msg.data & ~(DA9052_GPIO0203_GPIO2PIN)); ret = da9052->write(da9052, &msg); if (ret != 0) goto err_ssc_comm; da9052_unlock(da9052); #endif #if 0 /* By default configure the Measurement sequence interval to 10ms */ msg.addr = DA9052_ADCCONT_REG; msg.data = 0; da9052_lock(da9052); ret = da9052->read(da9052, &msg); if (ret != 0) goto err_ssc_comm; /* Set the ADC MODE bit for 10msec sampling timer */ msg.data = (msg.data & ~(DA9052_ADCCONT_ADCMODE)); ret = da9052->write(da9052, &msg); if (ret != 0) goto err_ssc_comm; da9052_unlock(da9052); #endif return 0; err_ssc_comm: da9052_unlock(da9052); return -EIO; }
int da9052_ldo_buck_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { struct da9052_regulator_priv *priv = rdev_get_drvdata(rdev); struct da9052_ssc_msg ssc_msg; int id = rdev_get_id(rdev); int ret; int ldo_volt = 0; /* KPIT - Below if condition is there for added setvoltage attribute in sysfs */ if (0 == max_uV) max_uV = da9052_regulators[id].reg_const.max_uV; /* Compare voltage range */ if (min_uV > max_uV) return -EINVAL; /* Check Minimum/ Maximum voltage range */ if (min_uV < da9052_regulators[id].reg_const.min_uV || min_uV > da9052_regulators[id].reg_const.max_uV) return -EINVAL; if (max_uV < da9052_regulators[id].reg_const.min_uV || max_uV > da9052_regulators[id].reg_const.max_uV) return -EINVAL; /* Get the ldo register value */ /* Varying step size for BUCK PERI */ if ((da9052_regulators[id].reg_desc.id == DA9052_BUCK_PERI) && (min_uV >= DA9052_BUCK_PERI_VALUES_3000)) { ldo_volt = (DA9052_BUCK_PERI_VALUES_3000 - da9052_regulators[id].reg_const.min_uV)/ (da9052_regulators[id].step_uV); ldo_volt += (min_uV - DA9052_BUCK_PERI_VALUES_3000)/ (DA9052_BUCK_PERI_STEP_ABOVE_3000); } else{ ldo_volt = (min_uV - da9052_regulators[id].reg_const.min_uV)/ (da9052_regulators[id].step_uV); /* Check for maximum value */ if ((ldo_volt * da9052_regulators[id].step_uV) + da9052_regulators[id].reg_const.min_uV > max_uV) return -EINVAL; } /* Configure LDO Voltage, CONF bits */ ssc_msg.addr = da9052_regulators[id].reg_add; ssc_msg.data = 0; /* Read register */ da9052_lock(priv->da9052); ret = priv->da9052->read(priv->da9052, &ssc_msg); if (ret) { da9052_unlock(priv->da9052); return -EIO; } ssc_msg.data = (ssc_msg.data & ~(da9052_regulators[id].mask_bits)); ssc_msg.data |= ldo_volt; ret = priv->da9052->write(priv->da9052, &ssc_msg); if (ret) { da9052_unlock(priv->da9052); return -EIO; } /* Set the GO LDO/BUCk bits so that the voltage changes */ ssc_msg.addr = DA9052_SUPPLY_REG; ssc_msg.data = 0; ret = priv->da9052->read(priv->da9052, &ssc_msg); if (ret) { da9052_unlock(priv->da9052); return -EIO; } switch (id) { case DA9052_LDO2: ssc_msg.data = (ssc_msg.data | DA9052_SUPPLY_VLDO2GO); break; case DA9052_LDO3: ssc_msg.data = (ssc_msg.data | DA9052_SUPPLY_VLDO3GO); break; case DA9052_BUCK_CORE: ssc_msg.data = (ssc_msg.data | DA9052_SUPPLY_VBCOREGO); break; case DA9052_BUCK_PRO: ssc_msg.data = (ssc_msg.data | DA9052_SUPPLY_VBPROGO); break; case DA9052_BUCK_MEM: ssc_msg.data = (ssc_msg.data | DA9052_SUPPLY_VBMEMGO); break; default: da9052_unlock(priv->da9052); return -EINVAL; } ret = priv->da9052->write(priv->da9052, &ssc_msg); if (ret) { da9052_unlock(priv->da9052); return -EIO; } da9052_unlock(priv->da9052); return 0; }