diff options
author | Uladzimir Bely <u.bely@sam-solutions.net> | 2013-10-14 16:34:45 +0300 |
---|---|---|
committer | Justin Waters <justin.waters@timesys.com> | 2014-05-14 14:13:28 -0400 |
commit | d810893f275ff997afb422e09ddd37cca0ec019f (patch) | |
tree | 83ab662b3197a53703be261af2d3f355fe2895ad | |
parent | 20c85b216bc5cde51a2853b33971734375bf4291 (diff) |
Updated da9063 driver
New "clean" files provided by Dialog Semiconductor
Signed-off-by: Uladzimir Bely <u.bely@sam-solutions.net>
Signed-off-by: Christian Hemp <c.hemp@phytec.de>
-rw-r--r-- | drivers/hwmon/da9063-hwmon.c | 9 | ||||
-rw-r--r-- | drivers/input/misc/da9063-onkey.c | 104 | ||||
-rw-r--r-- | drivers/mfd/da9063-core.c | 125 | ||||
-rw-r--r-- | drivers/mfd/da9063-i2c.c | 39 | ||||
-rw-r--r-- | drivers/mfd/da9063-irq.c | 11 | ||||
-rw-r--r-- | drivers/regulator/da9063-regulator.c | 417 | ||||
-rw-r--r-- | drivers/rtc/rtc-da9063.c | 322 | ||||
-rw-r--r-- | include/linux/mfd/da9063/core.h | 14 | ||||
-rw-r--r-- | include/linux/mfd/da9063/pdata.h | 7 | ||||
-rw-r--r-- | include/linux/mfd/da9063/registers.h | 172 |
10 files changed, 758 insertions, 462 deletions
diff --git a/drivers/hwmon/da9063-hwmon.c b/drivers/hwmon/da9063-hwmon.c index 4246d9d4410d..cf42a37841d3 100644 --- a/drivers/hwmon/da9063-hwmon.c +++ b/drivers/hwmon/da9063-hwmon.c @@ -1,7 +1,6 @@ - /* da9063-hwmon.c - Hardware monitor support for DA9063 - * Copyright (C) 2012 Dialog Semiconductor Ltd. - * + * Copyright (C) 2013 Dialog Semiconductor Ltd. + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -180,7 +179,7 @@ static ssize_t da9063_adc_read(struct device *dev, if (channel == DA9063_TJUNC) val += hwmon->tjunc_offset; - + val = da9063_adc_convert(channel, val); return sprintf(buf, "%d\n", val); @@ -313,7 +312,7 @@ static int __devinit da9063_hwmon_probe(struct platform_device *pdev) sysfs_remove_group(&pdev->dev.kobj, &da9063_attr_group); return PTR_ERR(hwmon->class_dev); } - + return 0; } diff --git a/drivers/input/misc/da9063-onkey.c b/drivers/input/misc/da9063-onkey.c index 5f6adfbc6521..8ec1c6784e17 100644 --- a/drivers/input/misc/da9063-onkey.c +++ b/drivers/input/misc/da9063-onkey.c @@ -1,7 +1,6 @@ - /* da9063-onkey.c - Onkey device driver for DA9063 - * Copyright (C) 2012 Dialog Semiconductor Ltd. - * + * Copyright (C) 2013 Dialog Semiconductor Ltd. + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -35,33 +34,104 @@ struct da9063_onkey { struct da9063 *da9063; + struct delayed_work work; struct input_dev *input; int irq; bool key_power; }; +static void da9063_poll_on(struct work_struct *work) +{ + u8 value; + int poll = 1; + int mask_events = 0; + int ret; + struct da9063_onkey *onkey = container_of(work, struct da9063_onkey, + work.work); + + /* poll to see when the pin is deasserted */ + ret = da9063_reg_read(onkey->da9063, DA9063_REG_STATUS_A); + if (ret >= 0 ) + { + if( !(ret & DA9063_NONKEY)) { + ret = da9063_reg_read(onkey->da9063, DA9063_REG_CONTROL_B); + if( ret >= 0 ) + { + ret &= ~(DA9063_NONKEY_LOCK); + value = ret; + ret = da9063_reg_write(onkey->da9063, DA9063_REG_CONTROL_B, value ); + if( ret < 0 ) + dev_err(&onkey->input->dev, "Failed to reset the Key_Delay %d\n", ret); + } + else { + dev_err(&onkey->input->dev, + "Failed to read DA9063_REG_CONTROL_B while trying to reset ONKEY %d\n", ret); + } + + input_report_key(onkey->input, KEY_POWER, 0); + input_sync(onkey->input); + + /* unmask the onkey interrupt again */ + mask_events = da9063_reg_read(onkey->da9063, DA9063_REG_IRQ_MASK_A ); + if (mask_events >= 0) { + mask_events &= ~(DA9063_NONKEY); + ret = da9063_reg_write(onkey->da9063, DA9063_REG_IRQ_MASK_A, mask_events); + if (ret < 0) { + dev_err(&onkey->input->dev, "Failed to unmask the onkey IRQ: %d\n", ret); + } + } + else { + dev_err(&onkey->input->dev, "Failed to unmask the onkey IRQ: %d\n", ret); + } + + poll = 0; + } + } + else { + dev_err(&onkey->input->dev, "Failed to read ON status: %d\n", ret); + } + + if( poll ) + schedule_delayed_work(&onkey->work, 50); +} + static irqreturn_t da9063_onkey_irq_handler(int irq, void *data) { struct da9063_onkey *onkey = data; - unsigned int code; int ret; + int mask_events = 0; ret = da9063_reg_read(onkey->da9063, DA9063_REG_STATUS_A); /* only report POWER if the key_power option is supported by driver */ - if (onkey->key_power && (ret >= 0) && (ret & DA9063_NONKEY)) { + if (onkey->key_power && (ret >= 0) && (ret & DA9063_NONKEY)) + { dev_notice(&onkey->input->dev, "KEY_POWER pressed.\n"); - code = KEY_POWER; - } else { + + /* mask the onkey interrupt until power key unpressed */ + mask_events = da9063_reg_read(onkey->da9063, DA9063_REG_IRQ_MASK_A); + if (mask_events >= 0) { + mask_events |= DA9063_NONKEY; + ret = da9063_reg_write(onkey->da9063, DA9063_REG_IRQ_MASK_A, mask_events); + if (ret < 0) { + dev_err(&onkey->input->dev, "Failed to mask the onkey IRQ: %d\n", ret); + } + } + else { + dev_err(&onkey->input->dev, "Failed to mask the onkey IRQ: %d\n", ret); + } + + input_report_key(onkey->input, KEY_POWER, 1); + input_sync(onkey->input); + + schedule_delayed_work(&onkey->work, 0); + } + else { dev_notice(&onkey->input->dev, "KEY_SLEEP pressed.\n"); - code = KEY_SLEEP; + input_report_key(onkey->input, KEY_SLEEP, 1); + input_report_key(onkey->input, KEY_SLEEP, 0); + input_sync(onkey->input); } - /* Interrupt raised for key release only, - so report consecutive button press and release. */ - input_report_key(onkey->input, code, 1); - input_report_key(onkey->input, code, 0); - input_sync(onkey->input); - return IRQ_HANDLED; } @@ -74,7 +144,7 @@ static int __devinit da9063_onkey_probe(struct platform_device *pdev) int ret = 0; /* driver assumes CONFIG_I register is set to DA9063_NONKEY_PIN_SWDOWN */ - if( pdata ) + if( pdata ) kp_tmp = pdata->key_power; if( !kp_tmp ) { @@ -88,6 +158,8 @@ static int __devinit da9063_onkey_probe(struct platform_device *pdev) return -ENOMEM; } + INIT_DELAYED_WORK(&onkey->work, da9063_poll_on); + onkey->input = input_allocate_device(); if (!onkey->input) { dev_err(&pdev->dev, "Failed to allocated input device.\n"); @@ -134,6 +206,8 @@ static int __devexit da9063_onkey_remove(struct platform_device *pdev) { struct da9063_onkey *onkey = platform_get_drvdata(pdev); + cancel_delayed_work_sync(&onkey->work); + free_irq(onkey->irq, onkey); input_unregister_device(onkey->input); return 0; diff --git a/drivers/mfd/da9063-core.c b/drivers/mfd/da9063-core.c index d079e02d019d..8c4fb8d570f3 100644 --- a/drivers/mfd/da9063-core.c +++ b/drivers/mfd/da9063-core.c @@ -1,7 +1,6 @@ - /* da9063-core.c - Core MFD device driver for DA9063 - * Copyright (C) 2012 Dialog Semiconductor Ltd. - * + * Copyright (C) 2013 Dialog Semiconductor Ltd. + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -101,6 +100,53 @@ static struct mfd_cell da9063_devs[] = { }, }; +static int da9063_init_page(struct da9063 *da9063) +{ + u8 val = DA9063_REG_PAGE0; + int ret = 0; + + mutex_lock(&da9063->io_mutex); + ret = da9063_write_device(da9063, DA9063_REG_PAGE_CON, 1, &val); + mutex_unlock(&da9063->io_mutex); + + return ret; +} + +int da9063_page_reg_read(struct da9063 *da9063, u16 reg) +{ + u8 pmic_page = DA9063_I2C_PAGE(reg); + u8 pmic_reg = DA9063_I2C_REG(reg); + u8 val; + int ret, ret2; + + mutex_lock(&da9063->io_mutex); + + if (pmic_page != DA9063_REG_PAGE0) { + ret = da9063_write_device(da9063, DA9063_REG_PAGE_CON, 1, + &pmic_page); + if (ret) + goto out; + } + + ret = da9063_read_device(da9063, pmic_reg, 1, &val); + + if (pmic_page != DA9063_REG_PAGE0) { + pmic_page = DA9063_REG_PAGE0; + ret2 = da9063_write_device(da9063, DA9063_REG_PAGE_CON, 1, + &pmic_page); + if (ret2 && ret == 0) + ret = ret2; + } + +out: + mutex_unlock(&da9063->io_mutex); + + if (ret) + return ret; + + return val; +} + int da9063_reg_read(struct da9063 *da9063, u16 reg) { u8 val; @@ -181,6 +227,63 @@ int da9063_reg_clear_bits(struct da9063 *da9063, u16 reg, u8 mask) return da9063_reg_update(da9063, reg, mask, 0); } +int da9063_get_trim_data(struct da9063 *da9063) +{ + signed int t_offset; + signed int model; + signed int revision; + + /* model */ + model = da9063_page_reg_read(da9063, DA9063_REG_CHIP_ID); + if (model < 0) { + dev_err(da9063->dev, "Cannot read chip model id.\n"); + return -EIO; + } + else { + if( (unsigned int)model != DA9063_ID ) { + dev_info(da9063->dev, + "Unknown device detected (expected DA9063)\n"); + return -EINVAL; + } + + da9063->model = (unsigned int)model; + } + + /* revision */ + revision = da9063_page_reg_read(da9063, DA9063_REG_CHIP_VARIANT); + if (revision < 0) { + dev_err(da9063->dev, "Cannot read chip revision id.\n"); + return -EIO; + } + else { + if( (unsigned int)revision != DA9063_AD_REVISION && + (unsigned int)revision < DA9063_BB_REVISION ) { + dev_info(da9063->dev, + "Unknown device revision detected\n"); + return -EINVAL; + } + + da9063->revision = (unsigned int)revision; + } + + dev_info(da9063->dev, + "Device detected (model-ID: 0x%02X rev-ID: 0x%02X)\n", da9063->model, da9063->revision); + + /* temperature offset */ + t_offset = da9063_page_reg_read(da9063, DA9063_REG_T_OFFSET); + if (t_offset < 0) { + dev_err(da9063->dev, "Cannot read chip temperature offset.\n"); + return -EIO; + } + else { + da9063->t_offset = (unsigned int)t_offset; + dev_info(da9063->dev, + "Trim measurements (t_offset: 0x%02X)\n", da9063->t_offset); + } + + return 0; +} + int da9063_device_init(struct da9063 *da9063, unsigned int irq) { struct da9063_pdata *pdata = da9063->dev->platform_data; @@ -204,6 +307,22 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq) } } + if (da9063_init_page(da9063)) { + dev_err(da9063->dev, "Cannot initialise page selector.\n"); + return -EIO; + } + + ret = da9063_get_trim_data(da9063); + if (ret < 0) { + dev_err(da9063->dev, "Cannot initialise trim data.\n"); + return ret; + } + + if (da9063_init_page(da9063)) { + dev_err(da9063->dev, "Cannot initialise page selector.\n"); + return -EIO; + } + ret = da9063_irq_init(da9063); if (ret) { dev_err(da9063->dev, "Cannot initialize interrupts.\n"); diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c index 36d23277f1c4..2039f6dfd021 100644 --- a/drivers/mfd/da9063-i2c.c +++ b/drivers/mfd/da9063-i2c.c @@ -1,7 +1,6 @@ - /* da9063-i2c.c - I2C device access for DA9063 - * Copyright (C) 2012 Dialog Semiconductor Ltd. - * + * Copyright (C) 2013 Dialog Semiconductor Ltd. + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -59,13 +58,19 @@ int da9063_read_device(struct da9063 *da9063, u8 reg, int da9063_write_device(struct da9063 *da9063, u8 reg, int bytes, const u8 *src) { - u8 buf[bytes + 1]; int ret; + u8 * buf = kzalloc( (bytes+1), GFP_KERNEL ); + + if( NULL == buf ) + return -ENOMEM; buf[0] = reg; memcpy(&buf[1], src, bytes); ret = i2c_master_send(da9063->i2c, buf, bytes + 1); + + kfree( buf ); + if (ret != bytes + 1) return -EIO; @@ -84,7 +89,6 @@ static int da9063_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, da9063); da9063->dev = &i2c->dev; da9063->i2c = i2c; - device_set_wakeup_capable(da9063->dev, 1); return da9063_device_init(da9063, i2c->irq); } @@ -104,28 +108,6 @@ static const struct i2c_device_id da9063_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, da9063_i2c_id); -static bool da9063_i2c_wakeup; - -static int da9063_i2c_suspend(struct i2c_client *i2c, pm_message_t state) -{ - if (device_may_wakeup(&i2c->dev)) { - enable_irq_wake(i2c->irq); - da9063_i2c_wakeup = 1; - } - - return 0; -} - -static int da9063_i2c_resume(struct i2c_client *i2c) -{ - if (i2c && da9063_i2c_wakeup) { - disable_irq_wake(i2c->irq); - da9063_i2c_wakeup = 0; - } - - return 0; -} - static struct i2c_driver da9063_i2c_driver = { .driver = { .name = "da9063", @@ -134,9 +116,6 @@ static struct i2c_driver da9063_i2c_driver = { .probe = da9063_i2c_probe, .remove = da9063_i2c_remove, .id_table = da9063_i2c_id, - - .suspend = da9063_i2c_suspend, - .resume = da9063_i2c_resume, }; static int __init da9063_i2c_init(void) diff --git a/drivers/mfd/da9063-irq.c b/drivers/mfd/da9063-irq.c index 0e0479be0c43..ff29e5e95e05 100644 --- a/drivers/mfd/da9063-irq.c +++ b/drivers/mfd/da9063-irq.c @@ -1,7 +1,6 @@ - /* da9063-irq.c - Interrupt support for DA9063 - * Copyright (C) 2012 Dialog Semiconductor Ltd. - * + * Copyright (C) 2013 Dialog Semiconductor Ltd. + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -233,9 +232,9 @@ static irqreturn_t da9063_irq_thread(int irq_id, void *da9063_data) return IRQ_NONE; } - for (i = DA9063_NUM_IRQ - 1; i >= 0; i--) { + for (i = DA9063_NUM_IRQ; i >= 0; i--) { irq = &da9063_irqs[i + DA9063_IRQ_BASE_OFFSET]; - if ((irq->mask & da9063->irq_masks[irq->reg]) && + if (!(irq->mask & da9063->irq_masks[irq->reg]) && irq->mask & events[irq->reg]) { handle_nested_irq(da9063->irq_base + i); error_detect = false; @@ -301,7 +300,7 @@ int da9063_irq_init(struct da9063 *da9063) #endif } - ret = devm_request_threaded_irq(da9063->dev, da9063->chip_irq, NULL, + ret = devm_request_threaded_irq(da9063->dev, da9063->chip_irq, NULL, da9063_irq_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "da9063-irq", da9063); if (ret) { diff --git a/drivers/regulator/da9063-regulator.c b/drivers/regulator/da9063-regulator.c index 2683f41bd968..a21f446c975c 100644 --- a/drivers/regulator/da9063-regulator.c +++ b/drivers/regulator/da9063-regulator.c @@ -1,7 +1,6 @@ - /* da9063-regulator.c - Regulator device driver for DA9063 - * Copyright (C) 2012 Dialog Semiconductor Ltd. - * + * Copyright (C) 2013 Dialog Semiconductor Ltd. + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -136,7 +135,7 @@ struct da9063_regulator_info { .mode = FIELD(DA9063_REG_##regl_name##_CFG, DA9063_BUCK_MODE_MASK, \ DA9063_BUCK_MODE_SHIFT, 0) -/* Defines asignment of regulators info table to chip model */ +/* Defines assignment of regulators info table to chip model */ struct da9063_dev_model { const struct da9063_regulator_info *regulator_info; unsigned n_regulators; @@ -267,143 +266,230 @@ static const int da9063_bmem_bio_merged_limits[] = { 4600000, 4800000, 5000000, 5200000, 5400000, 5600000, 5800000, 6000000 }; -/* Info of regulators for DA9063 */ -static const struct da9063_regulator_info da9063_regulator_info[] = { - { - DA9063_BUCK(DA9063, BCORE1, 300, 10, 1570, - da9063_buck_a_limits), - DA9063_BUCK_COMMON_FIELDS(BCORE1), - .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE1_SEL), - .ilimit = FIELD(DA9063_REG_BUCK_ILIM_C, DA9063_BCORE1_ILIM_MASK, - DA9063_BCORE1_ILIM_SHIFT, 0), - }, - { - DA9063_BUCK(DA9063, BCORE2, 300, 10, 1570, - da9063_buck_a_limits), - DA9063_BUCK_COMMON_FIELDS(BCORE2), - .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE2_SEL), - - .ilimit = FIELD(DA9063_REG_BUCK_ILIM_C, - DA9063_BCORE2_ILIM_MASK, - DA9063_BCORE2_ILIM_SHIFT, - 0), - }, - { - DA9063_BUCK(DA9063, BPRO, 530, 10, 1800, - da9063_buck_a_limits), - DA9063_BUCK_COMMON_FIELDS(BPRO), - .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBPRO_SEL), - .ilimit = FIELD(DA9063_REG_BUCK_ILIM_B, DA9063_BPRO_ILIM_MASK, - DA9063_BPRO_ILIM_SHIFT, 0), - }, - { - DA9063_BUCK(DA9063, BMEM, 800, 20, 3340, - da9063_buck_b_limits), - DA9063_BUCK_COMMON_FIELDS(BMEM), - .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBMEM_SEL), - .ilimit = FIELD(DA9063_REG_BUCK_ILIM_A, DA9063_BMEM_ILIM_MASK, - DA9063_BMEM_ILIM_SHIFT, 0), - }, - { - DA9063_BUCK(DA9063, BIO, 800, 20, 3340, - da9063_buck_b_limits), - DA9063_BUCK_COMMON_FIELDS(BIO), - .suspend = BFIELD(DA9063_REG_DVC_2, DA9063_VBIO_SEL), - .ilimit = FIELD(DA9063_REG_BUCK_ILIM_A, DA9063_BIO_ILIM_MASK, - DA9063_BIO_ILIM_SHIFT, 0), - }, - { - DA9063_BUCK(DA9063, BPERI, 800, 20, 3340, - da9063_buck_b_limits), - DA9063_BUCK_COMMON_FIELDS(BPERI), - .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBPERI_SEL), - .ilimit = FIELD(DA9063_REG_BUCK_ILIM_B, DA9063_BPERI_ILIM_MASK, - DA9063_BPERI_ILIM_SHIFT, 0), - }, - { - DA9063_BUCK(DA9063, BCORES_MERGED, 300, 10, 1570, - da9063_bcores_merged_limits), - /* BCORES_MERGED uses the same register fields as BCORE1 */ - DA9063_BUCK_COMMON_FIELDS(BCORE1), - .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE1_SEL), - .ilimit = FIELD(DA9063_REG_BUCK_ILIM_C, DA9063_BCORE1_ILIM_MASK, - DA9063_BCORE1_ILIM_SHIFT, 0), - }, - { - DA9063_BUCK(DA9063, BMEM_BIO_MERGED, 800, 20, 3340, - da9063_bmem_bio_merged_limits), - /* BMEM_BIO_MERGED uses the same register fields as BMEM */ - DA9063_BUCK_COMMON_FIELDS(BMEM), - .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBMEM_SEL), - .ilimit = FIELD(DA9063_REG_BUCK_ILIM_A, DA9063_BMEM_ILIM_MASK, - DA9063_BMEM_ILIM_SHIFT, 0), - }, - { - DA9063_LDO(DA9063, LDO1, 600, 20, 1860), - DA9063_LDO_COMMON_FIELDS(LDO1), - .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VLDO1_SEL), - }, - { - DA9063_LDO(DA9063, LDO2, 600, 20, 1860), - DA9063_LDO_COMMON_FIELDS(LDO2), - .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VLDO2_SEL), - }, - { - DA9063_LDO(DA9063, LDO3, 900, 20, 3440), - DA9063_LDO_COMMON_FIELDS(LDO3), - .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VLDO3_SEL), - .oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO3_LIM), - }, - { - DA9063_LDO(DA9063, LDO4, 900, 20, 3440), - DA9063_LDO_COMMON_FIELDS(LDO4), - .suspend = BFIELD(DA9063_REG_DVC_2, DA9063_VLDO4_SEL), - .oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO4_LIM), - }, - { - DA9063_LDO(DA9063, LDO5, 900, 50, 3600), - DA9063_LDO_COMMON_FIELDS(LDO5), - .suspend = BFIELD(DA9063_REG_LDO5_CONT, DA9063_VLDO5_SEL), - }, - { - DA9063_LDO(DA9063, LDO6, 900, 50, 3600), - DA9063_LDO_COMMON_FIELDS(LDO6), - .suspend = BFIELD(DA9063_REG_LDO6_CONT, DA9063_VLDO6_SEL), - }, - { - DA9063_LDO(DA9063, LDO7, 900, 50, 3600), - DA9063_LDO_COMMON_FIELDS(LDO7), - .suspend = BFIELD(DA9063_REG_LDO7_CONT, DA9063_VLDO7_SEL), - .oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO7_LIM), - }, - { - DA9063_LDO(DA9063, LDO8, 900, 50, 3600), - DA9063_LDO_COMMON_FIELDS(LDO8), - .suspend = BFIELD(DA9063_REG_LDO8_CONT, DA9063_VLDO8_SEL), - .oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO8_LIM), - }, - { - DA9063_LDO(DA9063, LDO9, 950, 50, 3600), - DA9063_LDO_COMMON_FIELDS(LDO9), - .suspend = BFIELD(DA9063_REG_LDO9_CONT, DA9063_VLDO9_SEL), - }, - { - DA9063_LDO(DA9063, LDO10, 900, 50, 3600), - DA9063_LDO_COMMON_FIELDS(LDO10), - .suspend = BFIELD(DA9063_REG_LDO10_CONT, DA9063_VLDO10_SEL), - }, - { - DA9063_LDO(DA9063, LDO11, 900, 50, 3600), - DA9063_LDO_COMMON_FIELDS(LDO11), - .suspend = BFIELD(DA9063_REG_LDO11_CONT, DA9063_VLDO11_SEL), - .oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO11_LIM), - }, - { - DA9063_SWITCH(DA9063, 32K_OUT), - .enable = BFIELD(DA9063_REG_EN_32K, DA9063_OUT_32K_EN), - }, +#define da9063_regulator_info_bcore1 { \ + DA9063_BUCK(DA9063, BCORE1, 300, 10, 1570, \ + da9063_buck_a_limits), \ + DA9063_BUCK_COMMON_FIELDS(BCORE1), \ + .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE1_SEL), \ + .ilimit = FIELD(DA9063_REG_BUCK_ILIM_C, DA9063_BCORE1_ILIM_MASK, \ + DA9063_BCORE1_ILIM_SHIFT, 0), \ + } + +#define da9063_regulator_info_bcore2 { \ + DA9063_BUCK(DA9063, BCORE2, 300, 10, 1570, \ + da9063_buck_a_limits), \ + DA9063_BUCK_COMMON_FIELDS(BCORE2), \ + .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE2_SEL), \ + .ilimit = FIELD(DA9063_REG_BUCK_ILIM_C, \ + DA9063_BCORE2_ILIM_MASK, \ + DA9063_BCORE2_ILIM_SHIFT, \ + 0), \ + } + +#define da9063_regulator_info_bpro { \ + DA9063_BUCK(DA9063, BPRO, 530, 10, 1800, \ + da9063_buck_a_limits), \ + DA9063_BUCK_COMMON_FIELDS(BPRO), \ + .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBPRO_SEL), \ + .ilimit = FIELD(DA9063_REG_BUCK_ILIM_B, DA9063_BPRO_ILIM_MASK, \ + DA9063_BPRO_ILIM_SHIFT, 0), \ + } + +#define da9063_regulator_info_bmem_a { \ + DA9063_BUCK(DA9063, BMEM, 800, 20, 3340, \ + da9063_buck_a_limits), \ + DA9063_BUCK_COMMON_FIELDS(BMEM), \ + .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBMEM_SEL), \ + .ilimit = FIELD(DA9063_REG_BUCK_ILIM_A, DA9063_BMEM_ILIM_MASK, \ + DA9063_BMEM_ILIM_SHIFT, 0), \ + } + +#define da9063_regulator_info_bmem_b { \ + DA9063_BUCK(DA9063, BMEM, 800, 20, 3340, \ + da9063_buck_b_limits), \ + DA9063_BUCK_COMMON_FIELDS(BMEM), \ + .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBMEM_SEL), \ + .ilimit = FIELD(DA9063_REG_BUCK_ILIM_A, DA9063_BMEM_ILIM_MASK, \ + DA9063_BMEM_ILIM_SHIFT, 0), \ + } + +#define da9063_regulator_info_bio_a { \ + DA9063_BUCK(DA9063, BIO, 800, 20, 3340, \ + da9063_buck_a_limits), \ + DA9063_BUCK_COMMON_FIELDS(BIO), \ + .suspend = BFIELD(DA9063_REG_DVC_2, DA9063_VBIO_SEL), \ + .ilimit = FIELD(DA9063_REG_BUCK_ILIM_A, DA9063_BIO_ILIM_MASK, \ + DA9063_BIO_ILIM_SHIFT, 0), \ + } + +#define da9063_regulator_info_bio_b { \ + DA9063_BUCK(DA9063, BIO, 800, 20, 3340, \ + da9063_buck_b_limits), \ + DA9063_BUCK_COMMON_FIELDS(BIO), \ + .suspend = BFIELD(DA9063_REG_DVC_2, DA9063_VBIO_SEL), \ + .ilimit = FIELD(DA9063_REG_BUCK_ILIM_A, DA9063_BIO_ILIM_MASK, \ + DA9063_BIO_ILIM_SHIFT, 0), \ + } + +#define da9063_regulator_info_bperi_a { \ + DA9063_BUCK(DA9063, BPERI, 800, 20, 3340, \ + da9063_buck_a_limits), \ + DA9063_BUCK_COMMON_FIELDS(BPERI), \ + .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBPERI_SEL), \ + .ilimit = FIELD(DA9063_REG_BUCK_ILIM_B, DA9063_BPERI_ILIM_MASK, \ + DA9063_BPERI_ILIM_SHIFT, 0), \ + } + +#define da9063_regulator_info_bperi_b { \ + DA9063_BUCK(DA9063, BPERI, 800, 20, 3340, \ + da9063_buck_b_limits), \ + DA9063_BUCK_COMMON_FIELDS(BPERI), \ + .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBPERI_SEL), \ + .ilimit = FIELD(DA9063_REG_BUCK_ILIM_B, DA9063_BPERI_ILIM_MASK, \ + DA9063_BPERI_ILIM_SHIFT, 0), \ + } + +#define da9063_regulator_info_bcores_merged { \ + DA9063_BUCK(DA9063, BCORES_MERGED, 300, 10, 1570, \ + da9063_bcores_merged_limits), \ + DA9063_BUCK_COMMON_FIELDS(BCORE1), \ + .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBCORE1_SEL), \ + .ilimit = FIELD(DA9063_REG_BUCK_ILIM_C, DA9063_BCORE1_ILIM_MASK, \ + DA9063_BCORE1_ILIM_SHIFT, 0), \ + } + +#define da9063_regulator_info_bmem_bio_merged { \ + DA9063_BUCK(DA9063, BMEM_BIO_MERGED, 800, 20, 3340, \ + da9063_bmem_bio_merged_limits), \ + DA9063_BUCK_COMMON_FIELDS(BMEM), \ + .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VBMEM_SEL), \ + .ilimit = FIELD(DA9063_REG_BUCK_ILIM_A, DA9063_BMEM_ILIM_MASK, \ + DA9063_BMEM_ILIM_SHIFT, 0), \ + } + +#define da9063_regulator_info_ldo1 { \ + DA9063_LDO(DA9063, LDO1, 600, 20, 1860), \ + DA9063_LDO_COMMON_FIELDS(LDO1), \ + .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VLDO1_SEL), \ + } + +#define da9063_regulator_info_ldo2 { \ + DA9063_LDO(DA9063, LDO2, 600, 20, 1860), \ + DA9063_LDO_COMMON_FIELDS(LDO2), \ + .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VLDO2_SEL), \ + } + +#define da9063_regulator_info_ldo3 { \ + DA9063_LDO(DA9063, LDO3, 900, 20, 3440), \ + DA9063_LDO_COMMON_FIELDS(LDO3), \ + .suspend = BFIELD(DA9063_REG_DVC_1, DA9063_VLDO3_SEL), \ + .oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO3_LIM), \ + } + +#define da9063_regulator_info_ldo4 { \ + DA9063_LDO(DA9063, LDO4, 900, 20, 3440), \ + DA9063_LDO_COMMON_FIELDS(LDO4), \ + .suspend = BFIELD(DA9063_REG_DVC_2, DA9063_VLDO4_SEL), \ + .oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO4_LIM), \ + } + +#define da9063_regulator_info_ldo5 { \ + DA9063_LDO(DA9063, LDO5, 900, 50, 3600), \ + DA9063_LDO_COMMON_FIELDS(LDO5), \ + .suspend = BFIELD(DA9063_REG_LDO5_CONT, DA9063_VLDO5_SEL), \ + } + +#define da9063_regulator_info_ldo6 { \ + DA9063_LDO(DA9063, LDO6, 900, 50, 3600), \ + DA9063_LDO_COMMON_FIELDS(LDO6), \ + .suspend = BFIELD(DA9063_REG_LDO6_CONT, DA9063_VLDO6_SEL), \ + } + +#define da9063_regulator_info_ldo7 { \ + DA9063_LDO(DA9063, LDO7, 900, 50, 3600), \ + DA9063_LDO_COMMON_FIELDS(LDO7), \ + .suspend = BFIELD(DA9063_REG_LDO7_CONT, DA9063_VLDO7_SEL), \ + .oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO7_LIM), \ + } + +#define da9063_regulator_info_ldo8 { \ + DA9063_LDO(DA9063, LDO8, 900, 50, 3600), \ + DA9063_LDO_COMMON_FIELDS(LDO8), \ + .suspend = BFIELD(DA9063_REG_LDO8_CONT, DA9063_VLDO8_SEL), \ + .oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO8_LIM), \ + } + +#define da9063_regulator_info_ldo9 { \ + DA9063_LDO(DA9063, LDO9, 950, 50, 3600), \ + DA9063_LDO_COMMON_FIELDS(LDO9), \ + .suspend = BFIELD(DA9063_REG_LDO9_CONT, DA9063_VLDO9_SEL), \ + } + +#define da9063_regulator_info_ldo10 { \ + DA9063_LDO(DA9063, LDO10, 900, 50, 3600), \ + DA9063_LDO_COMMON_FIELDS(LDO10), \ + .suspend = BFIELD(DA9063_REG_LDO10_CONT, DA9063_VLDO10_SEL), \ + } + +#define da9063_regulator_info_ldo11 { \ + DA9063_LDO(DA9063, LDO11, 900, 50, 3600), \ + DA9063_LDO_COMMON_FIELDS(LDO11), \ + .suspend = BFIELD(DA9063_REG_LDO11_CONT, DA9063_VLDO11_SEL), \ + .oc_event = BFIELD(DA9063_REG_STATUS_D, DA9063_LDO11_LIM), \ + } + +#define da9063_regulator_info_32k_out { \ + DA9063_SWITCH(DA9063, 32K_OUT), \ + .enable = BFIELD(DA9063_REG_EN_32K, DA9063_OUT_32K_EN), \ + } + +/* Info of regulators for DA9063-AD */ +static const struct da9063_regulator_info da9063_regulator_info_a[] = { + da9063_regulator_info_bcore1, + da9063_regulator_info_bcore2, + da9063_regulator_info_bpro, + da9063_regulator_info_bmem_a, + da9063_regulator_info_bio_a, + da9063_regulator_info_bperi_a, + da9063_regulator_info_bcores_merged, + da9063_regulator_info_bmem_bio_merged, + da9063_regulator_info_ldo1, + da9063_regulator_info_ldo2, + da9063_regulator_info_ldo3, + da9063_regulator_info_ldo4, + da9063_regulator_info_ldo5, + da9063_regulator_info_ldo6, + da9063_regulator_info_ldo7, + da9063_regulator_info_ldo8, + da9063_regulator_info_ldo9, + da9063_regulator_info_ldo10, + da9063_regulator_info_ldo11, + da9063_regulator_info_32k_out, }; +/* Info of regulators for DA9063-BB */ +static const struct da9063_regulator_info da9063_regulator_info_b[] = { + da9063_regulator_info_bcore1, + da9063_regulator_info_bcore2, + da9063_regulator_info_bpro, + da9063_regulator_info_bmem_b, + da9063_regulator_info_bio_b, + da9063_regulator_info_bperi_b, + da9063_regulator_info_bcores_merged, + da9063_regulator_info_bmem_bio_merged, + da9063_regulator_info_ldo1, + da9063_regulator_info_ldo2, + da9063_regulator_info_ldo3, + da9063_regulator_info_ldo4, + da9063_regulator_info_ldo5, + da9063_regulator_info_ldo6, + da9063_regulator_info_ldo7, + da9063_regulator_info_ldo8, + da9063_regulator_info_ldo9, + da9063_regulator_info_ldo10, + da9063_regulator_info_ldo11, + da9063_regulator_info_32k_out, +}; /* * Regulator internal functions */ @@ -584,8 +670,7 @@ static int da9063_set_voltage(struct regulator_dev *rdev, unsigned sel = da9063_min_val_to_sel(min_uV, regl->info->min_uV, regl->info->step_uV); - // ToDo: Fix voltage correction range, now enlarge to 1 step to be shure, that we in corretc range - if (da9063_sel_to_vol(regl, sel) > (max_uV + regl->info->step_uV)) + if (da9063_sel_to_vol(regl, sel) > max_uV) return -EINVAL; val = (sel + fvol->offset) << fvol->shift & fvol->mask; @@ -812,17 +897,29 @@ irqreturn_t da9063_ldo_lim_event(int irq, void *data) /* * Probing and Initialisation functions */ -static __devinit const struct da9063_regulator_info * da9063_get_regl_info(int id) +static __devinit const struct da9063_regulator_info * da9063_get_regl_info(int id, struct da9063 * chip) { int m; - for (m = ARRAY_SIZE(da9063_regulator_info) - 1; - da9063_regulator_info[m].id != id; m--) { - if (m <= 0) - return NULL; + switch( chip->revision ) { + case DA9063_AD_REVISION: + for (m = ARRAY_SIZE(da9063_regulator_info_a) - 1; + da9063_regulator_info_a[m].id != id; m--) { + if (m <= 0) + return NULL; + } + return &da9063_regulator_info_a[m]; + break; + + case DA9063_BB_REVISION: + default: + for (m = ARRAY_SIZE(da9063_regulator_info_b) - 1; + da9063_regulator_info_b[m].id != id; m--) { + if (m <= 0) + return NULL; + } + return &da9063_regulator_info_b[m]; } - - return &da9063_regulator_info[m]; } static __devinit int da9063_regulator_probe(struct platform_device *pdev) @@ -913,7 +1010,7 @@ static __devinit int da9063_regulator_probe(struct platform_device *pdev) /* Initialise regulator structure */ regl = ®ulators->regulator[n]; regl->hw = da9063; - regl->info = da9063_get_regl_info(rdata->id); + regl->info = da9063_get_regl_info(rdata->id, da9063); if (!regl->info) { dev_err(&pdev->dev, "Invalid regulator ID in platform data\n"); @@ -1007,27 +1104,6 @@ static int __devexit da9063_regulator_remove(struct platform_device *pdev) return 0; } -static void da9063_shutdown(struct platform_device *pdev) -{ - struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent); - int ret; - - /* VDDARM_IN 1.38V */ - ret = da9063_reg_write(da9063,DA9063_REG_VBCORE1_A,0x6C); - if (ret) - goto err; - - /* VDDSOC_IN 1.38V */ - ret = da9063_reg_write(da9063,DA9063_REG_VBCORE2_A,0x6C); - if (ret) - goto err; - - return; -err: - printk(KERN_ERR "%s Could not reset voltages!!!!\n", __func__); - -} - static struct platform_driver da9063_regulator_driver = { .driver = { .name = DA9063_DRVNAME_REGULATORS, @@ -1035,7 +1111,6 @@ static struct platform_driver da9063_regulator_driver = { }, .probe = da9063_regulator_probe, .remove = __devexit_p(da9063_regulator_remove), - .shutdown = da9063_shutdown, }; static int __init da9063_regulator_init(void) diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c index 4138272e5d89..8b4b7c5b12dd 100644 --- a/drivers/rtc/rtc-da9063.c +++ b/drivers/rtc/rtc-da9063.c @@ -1,7 +1,6 @@ - /* rtc-da9063.c - Real time clock device driver for DA9063 - * Copyright (C) 2012 Dialog Semiconductor Ltd. - * + * Copyright (C) 2013 Dialog Semiconductor Ltd. + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -29,13 +28,10 @@ #include <linux/mfd/da9063/registers.h> #include <linux/mfd/da9063/core.h> -#define YEARS_TO_DA9063(year) ((year) - 100) -#define MONTHS_TO_DA9063(month) ((month) + 1) -#define YEARS_FROM_DA9063(year) ((year) + 100) -#define MONTHS_FROM_DA9063(month) ((month) - 1) +#define CLOCK_DATA_LEN (DA9063_REG_COUNT_Y - DA9063_REG_COUNT_S + 1) +#define ALARM_AD_DATA_LEN (DA9063_AD_REG_ALARM_Y - DA9063_AD_REG_ALARM_MI + 1) +#define ALARM_DATA_LEN (DA9063_REG_ALARM_Y - DA9063_REG_ALARM_S + 1) -#define CLOCK_DATA_LEN (DA9063_REG_COUNT_Y - DA9063_REG_COUNT_S + 1) -#define ALARM_DATA_LEN (DA9063_REG_ALARM_Y - DA9063_REG_ALARM_MI + 1) enum { DATA_SEC = 0, DATA_MIN, @@ -49,87 +45,96 @@ struct da9063_rtc { struct rtc_device *rtc_dev; struct da9063 *hw; int irq_alarm; - int irq_tick; - - /* Config flag */ - int tick_wake; - - /* Used to expand alarm precision from minutes up to seconds - using hardware ticks */ - unsigned int alarmSecs; - unsigned int alarmTicks; + unsigned int chip_revision; }; static void da9063_data_to_tm(u8 *data, struct rtc_time *tm) { - tm->tm_sec = data[DATA_SEC] & DA9063_COUNT_SEC_MASK; - tm->tm_min = data[DATA_MIN] & DA9063_COUNT_MIN_MASK; - tm->tm_hour = data[DATA_HOUR] & DA9063_COUNT_HOUR_MASK; - tm->tm_mday = data[DATA_DAY] & DA9063_COUNT_DAY_MASK; - tm->tm_mon = MONTHS_FROM_DA9063(data[DATA_MONTH] & - DA9063_COUNT_MONTH_MASK); - tm->tm_year = YEARS_FROM_DA9063(data[DATA_YEAR] & - DA9063_COUNT_YEAR_MASK); + tm->tm_sec = (data[DATA_SEC] & DA9063_COUNT_SEC_MASK ); + tm->tm_min = (data[DATA_MIN] & DA9063_COUNT_MIN_MASK ); + tm->tm_hour = (data[DATA_HOUR] & DA9063_COUNT_HOUR_MASK ); + tm->tm_mday = (data[DATA_DAY] & DA9063_COUNT_DAY_MASK ); + /* conversion is from da9063 to real is month-1 and year-100 */ + tm->tm_mon = (data[DATA_MONTH] & DA9063_COUNT_MONTH_MASK) - 1; + tm->tm_year = (data[DATA_YEAR] & DA9063_COUNT_YEAR_MASK ) + 100; } static void da9063_tm_to_data(struct rtc_time *tm, u8 *data) { - data[DATA_SEC] &= ~DA9063_COUNT_SEC_MASK; - data[DATA_SEC] |= tm->tm_sec & DA9063_COUNT_SEC_MASK; - data[DATA_MIN] &= ~DA9063_COUNT_MIN_MASK; - data[DATA_MIN] |= tm->tm_min & DA9063_COUNT_MIN_MASK; - data[DATA_HOUR] &= ~DA9063_COUNT_HOUR_MASK; - data[DATA_HOUR] |= tm->tm_hour & DA9063_COUNT_HOUR_MASK; - data[DATA_DAY] &= ~DA9063_COUNT_DAY_MASK; - data[DATA_DAY] |= tm->tm_mday & DA9063_COUNT_DAY_MASK; + data[DATA_SEC] &= ~DA9063_COUNT_SEC_MASK; + data[DATA_SEC] |= tm->tm_sec & DA9063_COUNT_SEC_MASK; + + data[DATA_MIN] &= ~DA9063_COUNT_MIN_MASK; + data[DATA_MIN] |= tm->tm_min & DA9063_COUNT_MIN_MASK; + + data[DATA_HOUR] &= ~DA9063_COUNT_HOUR_MASK; + data[DATA_HOUR] |= tm->tm_hour & DA9063_COUNT_HOUR_MASK; + + data[DATA_DAY] &= ~DA9063_COUNT_DAY_MASK; + data[DATA_DAY] |= tm->tm_mday & DA9063_COUNT_DAY_MASK; + + /* conversion is from real to da9063 is month+1 */ data[DATA_MONTH] &= ~DA9063_COUNT_MONTH_MASK; - data[DATA_MONTH] |= MONTHS_TO_DA9063(tm->tm_mon) & - DA9063_COUNT_MONTH_MASK; - data[DATA_YEAR] &= ~DA9063_COUNT_YEAR_MASK; - data[DATA_YEAR] |= YEARS_TO_DA9063(tm->tm_year) & - DA9063_COUNT_YEAR_MASK; + data[DATA_MONTH] |= (tm->tm_mon+1) & DA9063_COUNT_MONTH_MASK; + + /* conversion is from real to da9063 is year-100 */ + data[DATA_YEAR] &= ~DA9063_COUNT_YEAR_MASK; + data[DATA_YEAR] |= (tm->tm_year-100) & DA9063_COUNT_YEAR_MASK; } -#define DA9063_ALARM_DELAY INT_MAX -static int da9063_rtc_test_delay(struct rtc_time *alarm, struct rtc_time *cur) +static int da9063_rtc_stop_alarm(struct device *dev) { - unsigned long a_time, c_time; - - rtc_tm_to_time(alarm, &a_time); - rtc_tm_to_time(cur, &c_time); - - /* Alarm time has already passed */ - if (a_time < c_time) - return -1; - - /* If alarm is set for current minute, return ticks to count down. - If alarm is set for following minutes, return DA9063_ALARM_DELAY - to set alarm first. - But when it is less than 2 seconds for the former to become true, - return ticks, because alarm needs some time to synchronise. */ - if (a_time - c_time < alarm->tm_sec + 2) - return a_time - c_time; - else - return DA9063_ALARM_DELAY; + struct da9063_rtc *rtc = dev_get_drvdata(dev); + int ret = 0; + + switch( rtc->chip_revision ) { + case DA9063_AD_REVISION: + ret = da9063_reg_clear_bits(rtc->hw, DA9063_AD_REG_ALARM_Y, DA9063_ALARM_ON); + break; + case DA9063_BB_REVISION: + default: + ret = da9063_reg_clear_bits(rtc->hw, DA9063_REG_ALARM_Y, DA9063_ALARM_ON); + } + + return ret; +} + +static int da9063_rtc_start_alarm(struct device *dev) +{ + struct da9063_rtc *rtc = dev_get_drvdata(dev); + int ret = 0; + + switch( rtc->chip_revision ) { + case DA9063_AD_REVISION: + ret = da9063_reg_set_bits(rtc->hw, DA9063_AD_REG_ALARM_Y, DA9063_ALARM_ON); + break; + case DA9063_BB_REVISION: + default: + ret = da9063_reg_set_bits(rtc->hw, DA9063_REG_ALARM_Y, DA9063_ALARM_ON); + } + + return ret; } static int da9063_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct da9063_rtc *rtc = dev_get_drvdata(dev); - u8 data[CLOCK_DATA_LEN]; + u8 data[CLOCK_DATA_LEN] = { [0 ... (CLOCK_DATA_LEN - 1)] = 0 }; int ret; ret = da9063_block_read(rtc->hw, DA9063_REG_COUNT_S, CLOCK_DATA_LEN, data); - if (ret < 0) + if (ret < 0) { + dev_err(dev, "Failed to read RTC time data: %d\n", ret); return ret; + } - /* Check, if RTC logic is initialised */ - if (!(data[DATA_SEC] & DA9063_RTC_READ)) - return -EBUSY; + if (!(data[DATA_SEC] & DA9063_RTC_READ)) { + dev_dbg(dev, "RTC not yet ready to be read by the host\n"); + return -EINVAL; + } da9063_data_to_tm(data, tm); - return rtc_valid_tm(tm); } @@ -143,6 +148,10 @@ static int da9063_rtc_set_time(struct device *dev, struct rtc_time *tm) ret = da9063_block_write(rtc->hw, DA9063_REG_COUNT_S, CLOCK_DATA_LEN, data); + if (ret < 0) { + dev_err(dev, "Failed to set RTC time data: %d\n", ret); + return ret; + } return ret; } @@ -150,29 +159,35 @@ static int da9063_rtc_set_time(struct device *dev, struct rtc_time *tm) static int da9063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct da9063_rtc *rtc = dev_get_drvdata(dev); - u8 data[CLOCK_DATA_LEN]; + u8 data[CLOCK_DATA_LEN] = { [0 ... (CLOCK_DATA_LEN - 1)] = 0 }; int ret; - ret = da9063_block_read(rtc->hw, DA9063_REG_ALARM_MI, ALARM_DATA_LEN, - &data[DATA_MIN]); + switch( rtc->chip_revision ) { + case DA9063_AD_REVISION: + ret = da9063_block_read(rtc->hw, DA9063_AD_REG_ALARM_MI, + ALARM_AD_DATA_LEN, &data[DATA_MIN]); + break; + case DA9063_BB_REVISION: + default: + ret = da9063_block_read(rtc->hw, DA9063_REG_ALARM_S, + ALARM_DATA_LEN, &data[DATA_SEC]); + } + if (ret < 0) return ret; da9063_data_to_tm(data, &alrm->time); - alrm->time.tm_sec = rtc->alarmSecs; alrm->enabled = !!(data[DATA_YEAR] & DA9063_ALARM_ON); - /* If there is no ticks left to count down and RTC event is - not processed yet, indicate pending */ - if (rtc->alarmTicks == 0) { - ret = da9063_reg_read(rtc->hw, DA9063_REG_EVENT_A); - if (ret < 0) - return ret; - if (ret & (DA9063_E_ALARM | DA9063_E_TICK)) - alrm->pending = 1; - } else { + /* If RTC event is not processed yet, indicate pending */ + ret = da9063_reg_read(rtc->hw, DA9063_REG_EVENT_A); + if (ret < 0) + return ret; + + if (ret & (DA9063_E_ALARM)) + alrm->pending = 1; + else alrm->pending = 0; - } return 0; } @@ -181,67 +196,45 @@ static int da9063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct da9063_rtc *rtc = dev_get_drvdata(dev); u8 data[CLOCK_DATA_LEN] = { [0 ... (CLOCK_DATA_LEN - 1)] = 0 }; - struct rtc_time cur_tm; - int cmp_val; int ret; - data[DATA_MIN] = DA9063_ALARM_STATUS_ALARM; - data[DATA_MONTH] = DA9063_TICK_TYPE_SEC; - if (rtc->tick_wake) - data[DATA_MONTH] |= DA9063_TICK_WAKE; + da9063_tm_to_data(&alrm->time, data); - ret = da9063_rtc_read_time(dev, &cur_tm); - if (ret < 0) + ret = da9063_rtc_stop_alarm(dev); + if (ret < 0) { + dev_err(dev, "Failed to stop alarm: %d\n", ret); return ret; + } + + switch( rtc->chip_revision ) { + case DA9063_AD_REVISION: + ret= da9063_block_write(rtc->hw, DA9063_AD_REG_ALARM_MI, + ALARM_AD_DATA_LEN, &data[DATA_MIN]); + break; + case DA9063_BB_REVISION: + default: + ret= da9063_block_write(rtc->hw, DA9063_REG_ALARM_S, + ALARM_DATA_LEN, &data[DATA_SEC]); + } if (alrm->enabled) { - cmp_val = da9063_rtc_test_delay(&alrm->time, &cur_tm); - if (cmp_val == DA9063_ALARM_DELAY) { - /* Set alarm for longer delay */ - data[DATA_YEAR] |= DA9063_ALARM_ON; - } else if (cmp_val > 0) { - /* Count ticks for shorter delay */ - rtc->alarmTicks = cmp_val - 1; - data[DATA_YEAR] |= DA9063_TICK_ON; - } else if (cmp_val == 0) { - /* Just about time - report event */ - rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); + ret = da9063_rtc_start_alarm(dev); + if (ret < 0) { + dev_err(dev, "Failed to start alarm: %d\n", ret); + return ret; } } - da9063_tm_to_data(&alrm->time, data); - rtc->alarmSecs = alrm->time.tm_sec; - - return da9063_block_write(rtc->hw, DA9063_REG_ALARM_MI, ALARM_DATA_LEN, - &data[DATA_MIN]); + return ret; } static int da9063_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { - struct da9063_rtc *rtc = dev_get_drvdata(dev); - struct rtc_wkalrm alrm; - int ret; - - ret = da9063_reg_read(rtc->hw, DATA_YEAR); - if (ret < 0) - return ret; - if (enabled) { - /* Enable alarm, if it is not enabled already */ - if (!(ret & (DA9063_ALARM_ON | DA9063_TICK_ON))) { - ret = da9063_rtc_read_alarm(dev, &alrm); - if (ret < 0) - return ret; - - alrm.enabled = 1; - ret = da9063_rtc_set_alarm(dev, &alrm); - } - } else { - ret = da9063_reg_clear_bits(rtc->hw, DA9063_REG_ALARM_Y, - DA9063_ALARM_ON); - } - - return ret; + if (enabled) + return da9063_rtc_start_alarm(dev); + else + return da9063_rtc_stop_alarm(dev); } /* On alarm interrupt, start to count ticks to enable seconds precision @@ -250,30 +243,18 @@ static irqreturn_t da9063_alarm_event(int irq, void *data) { struct da9063_rtc *rtc = data; - if (rtc->alarmSecs) { - rtc->alarmTicks = rtc->alarmSecs - 1; - da9063_reg_update(rtc->hw, DA9063_REG_ALARM_Y, - DA9063_ALARM_ON | DA9063_TICK_ON, - DA9063_TICK_ON); - } else { + switch( rtc->chip_revision ) { + case DA9063_AD_REVISION: + da9063_reg_clear_bits(rtc->hw, DA9063_AD_REG_ALARM_Y, + DA9063_ALARM_ON); + break; + case DA9063_BB_REVISION: + default: da9063_reg_clear_bits(rtc->hw, DA9063_REG_ALARM_Y, DA9063_ALARM_ON); - rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); } - return IRQ_HANDLED; -} - -/* On tick interrupt, count down seconds left to timeout */ -static irqreturn_t da9063_tick_event(int irq, void *data) -{ - struct da9063_rtc *rtc = data; - - if (rtc->alarmTicks-- == 0) { - da9063_reg_clear_bits(rtc->hw, - DA9063_REG_ALARM_Y, DA9063_TICK_ON); - rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_UF); - } + rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); return IRQ_HANDLED; } @@ -291,7 +272,6 @@ static __devinit int da9063_rtc_probe(struct platform_device *pdev) struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent); struct da9063_rtc *rtc; int ret; - int alarm_mo; /* Enable RTC hardware */ ret = da9063_reg_set_bits(da9063, DA9063_REG_CONTROL_E, DA9063_RTC_EN); @@ -306,16 +286,39 @@ static __devinit int da9063_rtc_probe(struct platform_device *pdev) return ret; } - ret = da9063_reg_read(da9063, DA9063_REG_ALARM_MO); + /* Set alarm reason (alarm only, no tick) */ + switch( da9063->revision ) { + case DA9063_AD_REVISION: + ret = da9063_reg_clear_bits(da9063, DA9063_AD_REG_ALARM_MI, + DA9063_ALARM_STATUS_TICK | DA9063_ALARM_STATUS_ALARM ); + ret = da9063_reg_set_bits(da9063, DA9063_AD_REG_ALARM_MI, + DA9063_ALARM_STATUS_ALARM ); + break; + case DA9063_BB_REVISION: + default: + ret = da9063_reg_clear_bits(da9063, DA9063_REG_ALARM_S, + DA9063_ALARM_STATUS_TICK | DA9063_ALARM_STATUS_ALARM ); + ret = da9063_reg_set_bits(da9063, DA9063_REG_ALARM_S, + DA9063_ALARM_STATUS_ALARM ); + } + if (ret < 0) { - dev_err(&pdev->dev, "Failed to read RTC register.\n"); + dev_err(&pdev->dev, "Failed to access RTC alarm register.\n"); return ret; } - alarm_mo = ret; /* Make sure that ticks are disabled. */ - ret = da9063_reg_clear_bits(da9063, DA9063_REG_ALARM_Y, - DA9063_TICK_ON); + switch( da9063->revision ) { + case DA9063_AD_REVISION: + ret = da9063_reg_clear_bits(da9063, DA9063_AD_REG_ALARM_Y, + DA9063_TICK_ON); + break; + case DA9063_BB_REVISION: + default: + ret = da9063_reg_clear_bits(da9063, DA9063_REG_ALARM_Y, + DA9063_TICK_ON); + } + if (ret < 0) { dev_err(&pdev->dev, "Failed to access RTC alarm register.\n"); return ret; @@ -328,6 +331,7 @@ static __devinit int da9063_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rtc); + rtc->chip_revision = da9063->revision; rtc->hw = da9063; rtc->rtc_dev = rtc_device_register(DA9063_DRVNAME_RTC, &pdev->dev, &da9063_rtc_ops, THIS_MODULE); @@ -337,9 +341,6 @@ static __devinit int da9063_rtc_probe(struct platform_device *pdev) return PTR_ERR(rtc->rtc_dev); } - if (alarm_mo & DA9063_TICK_WAKE) - rtc->tick_wake = 1; - /* Register interrupts. Complain on errors but let device to be registered at least for date/time. */ rtc->irq_alarm = platform_get_irq_byname(pdev, "ALARM"); @@ -351,14 +352,6 @@ static __devinit int da9063_rtc_probe(struct platform_device *pdev) return 0; } - rtc->irq_tick = platform_get_irq_byname(pdev, "TICK"); - ret = request_threaded_irq(rtc->irq_tick, NULL, da9063_tick_event, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, "TICK", rtc); - if (ret) { - dev_err(&pdev->dev, "Failed to request TICK IRQ.\n"); - rtc->irq_tick = -ENXIO; - } - return 0; } @@ -369,9 +362,6 @@ static int __devexit da9063_rtc_remove(struct platform_device *pdev) if (rtc->irq_alarm >= 0) free_irq(rtc->irq_alarm, rtc); - if (rtc->irq_tick >= 0) - free_irq(rtc->irq_tick, rtc); - rtc_device_unregister(rtc->rtc_dev); return 0; } diff --git a/include/linux/mfd/da9063/core.h b/include/linux/mfd/da9063/core.h index 34c0e6a04534..884acd471773 100644 --- a/include/linux/mfd/da9063/core.h +++ b/include/linux/mfd/da9063/core.h @@ -1,7 +1,6 @@ - /* core.h - Definitions for DA9063 MFD driver - * Copyright (C) 2012 Dialog Semiconductor Ltd. - * + * Copyright (C) 2013 Dialog Semiconductor Ltd. + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -27,6 +26,10 @@ /* Dialog ID */ #define DA9063_ID 0x61 +/* Revision support */ +#define DA9063_AD_REVISION 0x30 +#define DA9063_BB_REVISION 0x50 + /* DA9063 modules */ #define DA9063_DRVNAME_CORE "da9063-core" #define DA9063_DRVNAME_REGULATORS "da9063-regulators" @@ -75,8 +78,9 @@ enum da9063_irqs { struct da9063 { /* Device */ struct device *dev; - unsigned short model; - unsigned short revision; + unsigned int model; + unsigned int revision; + unsigned int t_offset; /* Control interface */ struct mutex io_mutex; diff --git a/include/linux/mfd/da9063/pdata.h b/include/linux/mfd/da9063/pdata.h index a399c5904123..8b9917809f48 100644 --- a/include/linux/mfd/da9063/pdata.h +++ b/include/linux/mfd/da9063/pdata.h @@ -1,7 +1,6 @@ - /* pdata.h - Platform configuration options for DA9063 - * Copyright (C) 2012 Dialog Semiconductor Ltd. - * + * Copyright (C) 2013 Dialog Semiconductor Ltd. + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -80,7 +79,7 @@ struct da9063; struct da9063_pdata { int (*init)(struct da9063 *da9063); int irq_base; - /* driver behaviour and stup */ + /* driver behaviour and setup */ bool bcores_merged; bool bmem_bio_merged; bool key_power; diff --git a/include/linux/mfd/da9063/registers.h b/include/linux/mfd/da9063/registers.h index f90467e182be..ccc297ae0f98 100644 --- a/include/linux/mfd/da9063/registers.h +++ b/include/linux/mfd/da9063/registers.h @@ -1,7 +1,6 @@ - /* registers.h - Registers definition for DA9063 - * Copyright (C) 2012 Dialog Semiconductor Ltd. - * + * Copyright (C) 2013 Dialog Semiconductor Ltd. + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either @@ -21,6 +20,9 @@ #ifndef _DA9063_REG_H #define _DA9063_REG_H +#define DA9063_I2C_PAGE_SEL_SHIFT 1 +#define DA9063_I2C_PAGE(v) (((v) >> 8) << \ + DA9063_I2C_PAGE_SEL_SHIFT) #define DA9063_I2C_REG(v) ((v) & 0xFF) #define DA9063_EVENT_REG_NUM 4 @@ -32,9 +34,6 @@ /* Page 3 : SPI access 0x180 - 0x1FF */ #define DA9063_REG_PAGE_CON 0x00 -/* Create virtual range for pageable registers just above physical range */ -#define DA9063_MAPPING_BASE 0x100 - /* System Control and Event Registers */ #define DA9063_REG_STATUS_A 0x01 #define DA9063_REG_STATUS_B 0x02 @@ -66,9 +65,9 @@ #define DA9063_REG_GPIO_10_11 0x1A #define DA9063_REG_GPIO_12_13 0x1B #define DA9063_REG_GPIO_14_15 0x1C -#define DA9063_REG_GPIO_MODE_0_7 0x1D -#define DA9063_REG_GPIO_MODE_8_15 0x1E -#define DA9063_REG_GPIO_SWITCH_CONT 0x1F +#define DA9063_REG_GPIO_MODE0_7 0x1D +#define DA9063_REG_GPIO_MODE8_15 0x1E +#define DA9063_REG_SWITCH_CONT 0x1F /* Regulator Control Registers */ #define DA9063_REG_BCORE2_CONT 0x20 @@ -88,7 +87,7 @@ #define DA9063_REG_LDO9_CONT 0x2E #define DA9063_REG_LDO10_CONT 0x2F #define DA9063_REG_LDO11_CONT 0x30 -#define DA9063_REG_VIB 0x31 +#define DA9063_REG_SUPPLIES 0x31 #define DA9063_REG_DVC_1 0x32 #define DA9063_REG_DVC_2 0x33 @@ -102,9 +101,9 @@ #define DA9063_REG_ADCIN1_RES 0x3A #define DA9063_REG_ADCIN2_RES 0x3B #define DA9063_REG_ADCIN3_RES 0x3C -#define DA9063_REG_MON1_RES 0x3D -#define DA9063_REG_MON2_RES 0x3E -#define DA9063_REG_MON3_RES 0x3F +#define DA9063_REG_MON_A8_RES 0x03D +#define DA9063_REG_MON_A9_RES 0x03E +#define DA9063_REG_MON_A10_RES 0x03F /* RTC Calendar and Alarm Registers */ #define DA9063_REG_COUNT_S 0x40 @@ -113,15 +112,28 @@ #define DA9063_REG_COUNT_D 0x43 #define DA9063_REG_COUNT_MO 0x44 #define DA9063_REG_COUNT_Y 0x45 -#define DA9063_REG_ALARM_MI 0x46 -#define DA9063_REG_ALARM_H 0x47 -#define DA9063_REG_ALARM_D 0x48 -#define DA9063_REG_ALARM_MO 0x49 -#define DA9063_REG_ALARM_Y 0x4A -#define DA9063_REG_SECOND_A 0x4B -#define DA9063_REG_SECOND_B 0x4C -#define DA9063_REG_SECOND_C 0x4D -#define DA9063_REG_SECOND_D 0x4E +/* Old definitions for DA9063 */ +#define DA9063_AD_REG_ALARM_MI 0x46 +#define DA9063_AD_REG_ALARM_H 0x47 +#define DA9063_AD_REG_ALARM_D 0x48 +#define DA9063_AD_REG_ALARM_MO 0x49 +#define DA9063_AD_REG_ALARM_Y 0x4A +#define DA9063_AD_REG_SECOND_A 0x4B +#define DA9063_AD_REG_SECOND_B 0x4C +#define DA9063_AD_REG_SECOND_C 0x4D +#define DA9063_AD_REG_SECOND_D 0x4E +/* Definitions for DA9063 */ +#define DA9063_REG_ALARM_S 0x46 +#define DA9063_REG_ALARM_MI 0x47 +#define DA9063_REG_ALARM_H 0x48 +#define DA9063_REG_ALARM_D 0x49 +#define DA9063_REG_ALARM_MO 0x4A +#define DA9063_REG_ALARM_Y 0x4B +#define DA9063_REG_SECOND_A 0x4C +#define DA9063_REG_SECOND_B 0x4D +#define DA9063_REG_SECOND_C 0x4E +#define DA9063_REG_SECOND_D 0x4F + /* Sequencer Control Registers */ #define DA9063_REG_SEQ 0x81 @@ -231,35 +243,69 @@ #define DA9063_REG_CONFIG_J 0x10F #define DA9063_REG_CONFIG_K 0x110 #define DA9063_REG_CONFIG_L 0x111 -#define DA9063_REG_MON_REG_1 0x112 -#define DA9063_REG_MON_REG_2 0x113 -#define DA9063_REG_MON_REG_3 0x114 -#define DA9063_REG_MON_REG_4 0x115 -#define DA9063_REG_MON_REG_5 0x116 -#define DA9063_REG_MON_REG_6 0x117 -#define DA9063_REG_TRIM_CLDR 0x118 - -/* General Purpose Registers */ -#define DA9063_REG_GP_ID_0 0x119 -#define DA9063_REG_GP_ID_1 0x11A -#define DA9063_REG_GP_ID_2 0x11B -#define DA9063_REG_GP_ID_3 0x11C -#define DA9063_REG_GP_ID_4 0x11D -#define DA9063_REG_GP_ID_5 0x11E -#define DA9063_REG_GP_ID_6 0x11F -#define DA9063_REG_GP_ID_7 0x120 -#define DA9063_REG_GP_ID_8 0x121 -#define DA9063_REG_GP_ID_9 0x122 -#define DA9063_REG_GP_ID_10 0x123 -#define DA9063_REG_GP_ID_11 0x124 -#define DA9063_REG_GP_ID_12 0x125 -#define DA9063_REG_GP_ID_13 0x126 -#define DA9063_REG_GP_ID_14 0x127 -#define DA9063_REG_GP_ID_15 0x128 -#define DA9063_REG_GP_ID_16 0x129 -#define DA9063_REG_GP_ID_17 0x12A -#define DA9063_REG_GP_ID_18 0x12B -#define DA9063_REG_GP_ID_19 0x12C + +#define DA9063_REG_CONFIG_M 0x112 +#define DA9063_REG_CONFIG_N 0x113 + +/* DA9063-AD specific register map */ +#define DA9063_AD_REG_MON_REG_1 0x112 +#define DA9063_AD_REG_MON_REG_2 0x113 +#define DA9063_AD_REG_MON_REG_3 0x114 +#define DA9063_AD_REG_MON_REG_4 0x115 +#define DA9063_AD_REG_MON_REG_5 0x116 +#define DA9063_AD_REG_MON_REG_6 0x117 +#define DA9063_AD_REG_TRIM_CLDR 0x118 +/* DA9063-AD specific General Purpose Registers */ +#define DA9063_AD_REG_GP_ID_0 0x119 +#define DA9063_AD_REG_GP_ID_1 0x11A +#define DA9063_AD_REG_GP_ID_2 0x11B +#define DA9063_AD_REG_GP_ID_3 0x11C +#define DA9063_AD_REG_GP_ID_4 0x11D +#define DA9063_AD_REG_GP_ID_5 0x11E +#define DA9063_AD_REG_GP_ID_6 0x11F +#define DA9063_AD_REG_GP_ID_7 0x120 +#define DA9063_AD_REG_GP_ID_8 0x121 +#define DA9063_AD_REG_GP_ID_9 0x122 +#define DA9063_AD_REG_GP_ID_10 0x123 +#define DA9063_AD_REG_GP_ID_11 0x124 +#define DA9063_AD_REG_GP_ID_12 0x125 +#define DA9063_AD_REG_GP_ID_13 0x126 +#define DA9063_AD_REG_GP_ID_14 0x127 +#define DA9063_AD_REG_GP_ID_15 0x128 +#define DA9063_AD_REG_GP_ID_16 0x129 +#define DA9063_AD_REG_GP_ID_17 0x12A +#define DA9063_AD_REG_GP_ID_18 0x12B +#define DA9063_AD_REG_GP_ID_19 0x12C + +/* Da9063-BB specific register map */ +#define DA9063_REG_MON_REG_1 0x114 +#define DA9063_REG_MON_REG_2 0x115 +#define DA9063_REG_MON_REG_3 0x116 +#define DA9063_REG_MON_REG_4 0x117 +#define DA9063_REG_MON_REG_5 0x11E +#define DA9063_REG_MON_REG_6 0x11F +#define DA9063_REG_TRIM_CLDR 0x120 +/* DA9063-BB specific General Purpose Registers */ +#define DA9063_REG_GP_ID_0 0x121 +#define DA9063_REG_GP_ID_1 0x122 +#define DA9063_REG_GP_ID_2 0x123 +#define DA9063_REG_GP_ID_3 0x124 +#define DA9063_REG_GP_ID_4 0x125 +#define DA9063_REG_GP_ID_5 0x126 +#define DA9063_REG_GP_ID_6 0x127 +#define DA9063_REG_GP_ID_7 0x128 +#define DA9063_REG_GP_ID_8 0x129 +#define DA9063_REG_GP_ID_9 0x12A +#define DA9063_REG_GP_ID_10 0x12B +#define DA9063_REG_GP_ID_11 0x12C +#define DA9063_REG_GP_ID_12 0x12D +#define DA9063_REG_GP_ID_13 0x12E +#define DA9063_REG_GP_ID_14 0x12F +#define DA9063_REG_GP_ID_15 0x130 +#define DA9063_REG_GP_ID_16 0x131 +#define DA9063_REG_GP_ID_17 0x132 +#define DA9063_REG_GP_ID_18 0x133 +#define DA9063_REG_GP_ID_19 0x134 /* Chip ID and variant */ #define DA9063_REG_CHIP_ID 0x181 @@ -410,8 +456,10 @@ /* DA9063_REG_CONTROL_B (addr=0x0F) */ #define DA9063_CHG_SEL 0x01 #define DA9063_WATCHDOG_PD 0x02 +#define DA9063_RESET_BLINKING 0x04 #define DA9063_NRES_MODE 0x08 #define DA9063_NONKEY_LOCK 0x10 +#define DA9063_BUCK_SLOWSTART 0x80 /* DA9063_REG_CONTROL_C (addr=0x10) */ #define DA9063_DEBOUNCING_SHIFT 0 @@ -476,6 +524,7 @@ #define DA9063_GPADC_PAUSE 0x02 #define DA9063_PMIF_DIS 0x04 #define DA9063_HS2WIRE_DIS 0x08 +#define DA9063_CLDR_PAUSE 0x10 #define DA9063_BBAT_DIS 0x20 #define DA9063_OUT_32K_PAUSE 0x40 #define DA9063_PMCONT_DIS 0x80 @@ -731,7 +780,7 @@ #define DA9063_SWITCH_SR_5MV 0x10 #define DA9063_SWITCH_SR_10MV 0x20 #define DA9063_SWITCH_SR_50MV 0x30 -#define DA9063_SWITCH_SR_DIS 0x40 +#define DA9063_CORE_SW_INTERNAL 0x40 #define DA9063_CP_EN_MODE 0x80 /* DA9063_REGL_Bxxxx_CONT common bits (addr=0x20-0x25) */ @@ -879,25 +928,34 @@ #define DA9063_COUNT_YEAR_MASK 0x3F #define DA9063_MONITOR 0x40 -/* DA9063_REG_ALARM_MI (addr=0x46) */ +/* DA9063_REG_ALARM_S (addr=0x46) */ +#define DA9063_ALARM_S_MASK 0x3F +/* DA9063_REG_ALARM_S (addr=0x46) */ +/* DA9063_AD_REG_ALARM_MI (addr=0x46) */ #define DA9063_ALARM_STATUS_ALARM 0x80 #define DA9063_ALARM_STATUS_TICK 0x40 +/* DA9063_REG_ALARM_MI (addr=0x47) */ +/* DA9063_AD_REG_ALARM_MI (addr=0x46) */ #define DA9063_ALARM_MIN_MASK 0x3F -/* DA9063_REG_ALARM_H (addr=0x47) */ +/* DA9063_REG_ALARM_H (addr=0x48) */ +/* DA9063_AD_REG_ALARM_H (addr=0x47) */ #define DA9063_ALARM_HOUR_MASK 0x1F -/* DA9063_REG_ALARM_D (addr=0x48) */ +/* DA9063_REG_ALARM_D (addr=0x49) */ +/* DA9063_AD_REG_ALARM_D (addr=0x48) */ #define DA9063_ALARM_DAY_MASK 0x1F -/* DA9063_REG_ALARM_MO (addr=0x49) */ +/* DA9063_REG_ALARM_MO (addr=0x4A) */ +/* DA9063_AD_REG_ALARM_MO (addr=0x49) */ #define DA9063_TICK_WAKE 0x20 #define DA9063_TICK_TYPE 0x10 #define DA9063_TICK_TYPE_SEC 0x00 #define DA9063_TICK_TYPE_MIN 0x10 #define DA9063_ALARM_MONTH_MASK 0x0F -/* DA9063_REG_ALARM_Y (addr=0x4A) */ +/* DA9063_REG_ALARM_Y (addr=0x4B) */ +/* DA9063_AD_REG_ALARM_Y (addr=0x4A) */ #define DA9063_TICK_ON 0x80 #define DA9063_ALARM_ON 0x40 #define DA9063_ALARM_YEAR_MASK 0x3F |