static int da9052_wdt_ping(struct watchdog_device *wdt_dev) { struct da9052_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev); struct da9052 *da9052 = driver_data->da9052; unsigned long msec, jnow = jiffies; int ret; /* * We have a minimum time for watchdog window called TWDMIN. A write * to the watchdog before this elapsed time should cause an error. */ msec = (jnow - driver_data->jpast) * 1000/HZ; if (msec < DA9052_TWDMIN) mdelay(msec); /* Reset the watchdog timer */ ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG, DA9052_CONTROLD_WATCHDOG, 1 << 7); if (ret < 0) goto err_strobe; /* * FIXME: Reset the watchdog core, in general PMIC * is supposed to do this */ ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG, DA9052_CONTROLD_WATCHDOG, 0 << 7); err_strobe: return ret; }
static int da9052_configure_leds(struct da9052 *da9052) { int error; unsigned char register_value = DA9052_OPENDRAIN_OUTPUT | DA9052_SET_HIGH_LVL_OUTPUT; error = da9052_reg_update(da9052, DA9052_GPIO_14_15_REG, DA9052_MASK_LOWER_NIBBLE, register_value); if (error < 0) { dev_err(da9052->dev, "Failed to write GPIO 14-15 reg, %d\n", error); return error; } error = da9052_reg_update(da9052, DA9052_GPIO_14_15_REG, DA9052_MASK_UPPER_NIBBLE, register_value << DA9052_NIBBLE_SHIFT); if (error < 0) dev_err(da9052->dev, "Failed to write GPIO 14-15 reg, %d\n", error); return error; }
static int da9052_set_alarm(struct da9052 *da9052, struct rtc_time *rtc_tm) { int ret; uint8_t v[3]; rtc_tm->tm_year -= 100; rtc_tm->tm_mon += 1; ret = da9052_reg_update(da9052, DA9052_ALARM_MI_REG, DA9052_RTC_MIN, rtc_tm->tm_min); if (ret != 0) { rtc_err(da9052, "Failed to write ALRM MIN: %d\n", ret); return ret; } v[0] = rtc_tm->tm_hour; v[1] = rtc_tm->tm_mday; v[2] = rtc_tm->tm_mon; ret = da9052_group_write(da9052, DA9052_ALARM_H_REG, 3, v); if (ret < 0) return ret; ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG, DA9052_RTC_YEAR, rtc_tm->tm_year); if (ret != 0) rtc_err(da9052, "Failed to write ALRM YEAR: %d\n", ret); return ret; }
static int da9052_wdt_set_timeout(struct watchdog_device *wdt_dev, unsigned int timeout) { struct da9052_wdt_data *driver_data = watchdog_get_drvdata(wdt_dev); struct da9052 *da9052 = driver_data->da9052; int ret, i; /* * Disable the Watchdog timer before setting * new time out. */ ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG, DA9052_CONTROLD_TWDSCALE, 0); if (ret < 0) { dev_err(da9052->dev, "Failed to disable watchdog bit, %d\n", ret); return ret; } if (timeout) { /* * To change the timeout, da9052 needs to * be disabled for at least 150 us. */ udelay(150); /* Set the desired timeout */ for (i = 0; i < ARRAY_SIZE(da9052_wdt_maps); i++) if (da9052_wdt_maps[i].time == timeout) break; if (i == ARRAY_SIZE(da9052_wdt_maps)) ret = -EINVAL; else ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG, DA9052_CONTROLD_TWDSCALE, da9052_wdt_maps[i].reg_val); if (ret < 0) { dev_err(da9052->dev, "Failed to update timescale bit, %d\n", ret); return ret; } wdt_dev->timeout = timeout; driver_data->jpast = jiffies; } return 0; }
static int da9052_USB_current_notifier(struct notifier_block *nb, unsigned long events, void *data) { u8 row; u8 col; int *current_mA = data; int ret; struct da9052_battery *bat = container_of(nb, struct da9052_battery, nb); if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING) return -EPERM; ret = da9052_reg_read(bat->da9052, DA9052_CHGBUCK_REG); if (ret & DA9052_CHG_USB_ILIM_MASK) return -EPERM; if (bat->da9052->chip_id == DA9052) row = 0; else row = 1; if (*current_mA < da9052_chg_current_lim[row][0] || *current_mA > da9052_chg_current_lim[row][DA9052_CHG_LIM_COLS - 1]) return -EINVAL; for (col = 0; col <= DA9052_CHG_LIM_COLS - 1 ; col++) { if (*current_mA <= da9052_chg_current_lim[row][col]) break; } return da9052_reg_update(bat->da9052, DA9052_ISET_REG, DA9052_ISET_USB_MASK, col); }
static int da9052_rtc_probe(struct platform_device *pdev) { struct da9052_rtc *rtc; int ret; rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9052_rtc), GFP_KERNEL); if (!rtc) return -ENOMEM; rtc->da9052 = dev_get_drvdata(pdev->dev.parent); platform_set_drvdata(pdev, rtc); ret = da9052_reg_write(rtc->da9052, DA9052_BBAT_CONT_REG, 0xFE); if (ret < 0) { rtc_err(rtc, "Failed to setup RTC battery charging: %d\n", ret); return ret; } ret = da9052_reg_update(rtc->da9052, DA9052_ALARM_Y_REG, DA9052_ALARM_Y_TICK_ON, 0); if (ret != 0) rtc_err(rtc, "Failed to disable TICKS: %d\n", ret); ret = da9052_request_irq(rtc->da9052, DA9052_IRQ_ALARM, "ALM", da9052_rtc_irq, rtc); if (ret != 0) { rtc_err(rtc, "irq registration failed: %d\n", ret); return ret; } rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &da9052_rtc_ops, THIS_MODULE); return PTR_ERR_OR_ZERO(rtc->rtc); }
static int da9052_rtc_enable_alarm(struct da9052 *da9052, bool enable) { int ret; if (enable) { ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG, DA9052_ALARM_Y_ALARM_ON, DA9052_ALARM_Y_ALARM_ON); if (ret != 0) rtc_err(da9052, "Failed to enable ALM: %d\n", ret); } else { ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG, DA9052_ALARM_Y_ALARM_ON, 0); if (ret != 0) rtc_err(da9052, "Write error: %d\n", ret); } return ret; }
static int da9052_set_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm) { struct da9052 *da9052 = rtc->da9052; unsigned long alm_time; int ret; uint8_t v[3]; ret = rtc_tm_to_time(rtc_tm, &alm_time); if (ret != 0) return ret; if (rtc_tm->tm_sec > 0) { alm_time += 60 - rtc_tm->tm_sec; rtc_time_to_tm(alm_time, rtc_tm); } BUG_ON(rtc_tm->tm_sec); /* it will cause repeated irqs if not zero */ rtc_tm->tm_year -= 100; rtc_tm->tm_mon += 1; ret = da9052_reg_update(da9052, DA9052_ALARM_MI_REG, DA9052_RTC_MIN, rtc_tm->tm_min); if (ret != 0) { rtc_err(rtc, "Failed to write ALRM MIN: %d\n", ret); return ret; } v[0] = rtc_tm->tm_hour; v[1] = rtc_tm->tm_mday; v[2] = rtc_tm->tm_mon; ret = da9052_group_write(da9052, DA9052_ALARM_H_REG, 3, v); if (ret < 0) return ret; ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG, DA9052_RTC_YEAR, rtc_tm->tm_year); if (ret != 0) rtc_err(rtc, "Failed to write ALRM YEAR: %d\n", ret); return ret; }
static int da9052_wdt_probe(struct platform_device *pdev) { struct da9052 *da9052 = dev_get_drvdata(pdev->dev.parent); struct da9052_wdt_data *driver_data; struct watchdog_device *da9052_wdt; int ret; driver_data = devm_kzalloc(&pdev->dev, sizeof(*driver_data), GFP_KERNEL); if (!driver_data) { ret = -ENOMEM; goto err; } driver_data->da9052 = da9052; da9052_wdt = &driver_data->wdt; da9052_wdt->timeout = DA9052_DEF_TIMEOUT; da9052_wdt->info = &da9052_wdt_info; da9052_wdt->ops = &da9052_wdt_ops; da9052_wdt->parent = &pdev->dev; watchdog_set_drvdata(da9052_wdt, driver_data); ret = da9052_reg_update(da9052, DA9052_CONTROL_D_REG, DA9052_CONTROLD_TWDSCALE, 0); if (ret < 0) { dev_err(&pdev->dev, "Failed to disable watchdog bits, %d\n", ret); goto err; } ret = watchdog_register_device(&driver_data->wdt); if (ret != 0) { dev_err(da9052->dev, "watchdog_register_device() failed: %d\n", ret); goto err; } platform_set_drvdata(pdev, driver_data); err: return ret; }