Commit 28db38888b2a53b6bdd70104c2d2a199632ca507

Authored by Haojian Zhuang
Committed by Samuel Ortiz
1 parent a39069f6ce

power_supply: Enable power supply of max8925

MAX8925 is a PMIC that contains charger component

Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>

Showing 3 changed files with 542 additions and 0 deletions Side-by-side Diff

drivers/power/Kconfig
... ... @@ -29,6 +29,13 @@
29 29 Say Y here to enable support APM status emulation using
30 30 battery class devices.
31 31  
  32 +config MAX8925_POWER
  33 + tristate "MAX8925 battery charger support"
  34 + depends on MFD_MAX8925
  35 + help
  36 + Say Y here to enable support for the battery charger in the Maxim
  37 + MAX8925 PMIC.
  38 +
32 39 config WM831X_BACKUP
33 40 tristate "WM831X backup battery charger support"
34 41 depends on MFD_WM831X
drivers/power/Makefile
... ... @@ -16,6 +16,7 @@
16 16  
17 17 obj-$(CONFIG_PDA_POWER) += pda_power.o
18 18 obj-$(CONFIG_APM_POWER) += apm_power.o
  19 +obj-$(CONFIG_MAX8925_POWER) += max8925_power.o
19 20 obj-$(CONFIG_WM831X_BACKUP) += wm831x_backup.o
20 21 obj-$(CONFIG_WM831X_POWER) += wm831x_power.o
21 22 obj-$(CONFIG_WM8350_POWER) += wm8350_power.o
drivers/power/max8925_power.c
  1 +/*
  2 + * Battery driver for Maxim MAX8925
  3 + *
  4 + * Copyright (c) 2009-2010 Marvell International Ltd.
  5 + * Haojian Zhuang <haojian.zhuang@marvell.com>
  6 + *
  7 + * This program is free software; you can redistribute it and/or modify
  8 + * it under the terms of the GNU General Public License version 2 as
  9 + * published by the Free Software Foundation.
  10 + */
  11 +
  12 +#include <linux/module.h>
  13 +#include <linux/err.h>
  14 +#include <linux/i2c.h>
  15 +#include <linux/interrupt.h>
  16 +#include <linux/platform_device.h>
  17 +#include <linux/power_supply.h>
  18 +#include <linux/mfd/max8925.h>
  19 +
  20 +/* registers in GPM */
  21 +#define MAX8925_OUT5VEN 0x54
  22 +#define MAX8925_OUT3VEN 0x58
  23 +#define MAX8925_CHG_CNTL1 0x7c
  24 +
  25 +/* bits definition */
  26 +#define MAX8925_CHG_STAT_VSYSLOW (1 << 0)
  27 +#define MAX8925_CHG_STAT_MODE_MASK (3 << 2)
  28 +#define MAX8925_CHG_STAT_EN_MASK (1 << 4)
  29 +#define MAX8925_CHG_MBDET (1 << 1)
  30 +#define MAX8925_CHG_AC_RANGE_MASK (3 << 6)
  31 +
  32 +/* registers in ADC */
  33 +#define MAX8925_ADC_RES_CNFG1 0x06
  34 +#define MAX8925_ADC_AVG_CNFG1 0x07
  35 +#define MAX8925_ADC_ACQ_CNFG1 0x08
  36 +#define MAX8925_ADC_ACQ_CNFG2 0x09
  37 +/* 2 bytes registers in below. MSB is 1st, LSB is 2nd. */
  38 +#define MAX8925_ADC_AUX2 0x62
  39 +#define MAX8925_ADC_VCHG 0x64
  40 +#define MAX8925_ADC_VBBATT 0x66
  41 +#define MAX8925_ADC_VMBATT 0x68
  42 +#define MAX8925_ADC_ISNS 0x6a
  43 +#define MAX8925_ADC_THM 0x6c
  44 +#define MAX8925_ADC_TDIE 0x6e
  45 +#define MAX8925_CMD_AUX2 0xc8
  46 +#define MAX8925_CMD_VCHG 0xd0
  47 +#define MAX8925_CMD_VBBATT 0xd8
  48 +#define MAX8925_CMD_VMBATT 0xe0
  49 +#define MAX8925_CMD_ISNS 0xe8
  50 +#define MAX8925_CMD_THM 0xf0
  51 +#define MAX8925_CMD_TDIE 0xf8
  52 +
  53 +enum {
  54 + MEASURE_AUX2,
  55 + MEASURE_VCHG,
  56 + MEASURE_VBBATT,
  57 + MEASURE_VMBATT,
  58 + MEASURE_ISNS,
  59 + MEASURE_THM,
  60 + MEASURE_TDIE,
  61 + MEASURE_MAX,
  62 +};
  63 +
  64 +struct max8925_power_info {
  65 + struct max8925_chip *chip;
  66 + struct i2c_client *gpm;
  67 + struct i2c_client *adc;
  68 +
  69 + struct power_supply ac;
  70 + struct power_supply usb;
  71 + struct power_supply battery;
  72 + int irq_base;
  73 + unsigned ac_online:1;
  74 + unsigned usb_online:1;
  75 + unsigned bat_online:1;
  76 + unsigned chg_mode:2;
  77 + unsigned batt_detect:1; /* detecing MB by ID pin */
  78 + unsigned topoff_threshold:2;
  79 + unsigned fast_charge:3;
  80 +
  81 + int (*set_charger) (int);
  82 +};
  83 +
  84 +static int __set_charger(struct max8925_power_info *info, int enable)
  85 +{
  86 + struct max8925_chip *chip = info->chip;
  87 + if (enable) {
  88 + /* enable charger in platform */
  89 + if (info->set_charger)
  90 + info->set_charger(1);
  91 + /* enable charger */
  92 + max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 0);
  93 + } else {
  94 + /* disable charge */
  95 + max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 1 << 7);
  96 + if (info->set_charger)
  97 + info->set_charger(0);
  98 + }
  99 + dev_dbg(chip->dev, "%s\n", (enable) ? "Enable charger"
  100 + : "Disable charger");
  101 + return 0;
  102 +}
  103 +
  104 +static irqreturn_t max8925_charger_handler(int irq, void *data)
  105 +{
  106 + struct max8925_power_info *info = (struct max8925_power_info *)data;
  107 + struct max8925_chip *chip = info->chip;
  108 +
  109 + switch (irq - chip->irq_base) {
  110 + case MAX8925_IRQ_VCHG_DC_R:
  111 + info->ac_online = 1;
  112 + __set_charger(info, 1);
  113 + dev_dbg(chip->dev, "Adapter inserted\n");
  114 + break;
  115 + case MAX8925_IRQ_VCHG_DC_F:
  116 + info->ac_online = 0;
  117 + __set_charger(info, 0);
  118 + dev_dbg(chip->dev, "Adapter is removal\n");
  119 + break;
  120 + case MAX8925_IRQ_VCHG_USB_R:
  121 + info->usb_online = 1;
  122 + __set_charger(info, 1);
  123 + dev_dbg(chip->dev, "USB inserted\n");
  124 + break;
  125 + case MAX8925_IRQ_VCHG_USB_F:
  126 + info->usb_online = 0;
  127 + __set_charger(info, 0);
  128 + dev_dbg(chip->dev, "USB is removal\n");
  129 + break;
  130 + case MAX8925_IRQ_VCHG_THM_OK_F:
  131 + /* Battery is not ready yet */
  132 + dev_dbg(chip->dev, "Battery temperature is out of range\n");
  133 + case MAX8925_IRQ_VCHG_DC_OVP:
  134 + dev_dbg(chip->dev, "Error detection\n");
  135 + __set_charger(info, 0);
  136 + break;
  137 + case MAX8925_IRQ_VCHG_THM_OK_R:
  138 + /* Battery is ready now */
  139 + dev_dbg(chip->dev, "Battery temperature is in range\n");
  140 + break;
  141 + case MAX8925_IRQ_VCHG_SYSLOW_R:
  142 + /* VSYS is low */
  143 + dev_info(chip->dev, "Sys power is too low\n");
  144 + break;
  145 + case MAX8925_IRQ_VCHG_SYSLOW_F:
  146 + dev_dbg(chip->dev, "Sys power is above low threshold\n");
  147 + break;
  148 + case MAX8925_IRQ_VCHG_DONE:
  149 + __set_charger(info, 0);
  150 + dev_dbg(chip->dev, "Charging is done\n");
  151 + break;
  152 + case MAX8925_IRQ_VCHG_TOPOFF:
  153 + dev_dbg(chip->dev, "Charging in top-off mode\n");
  154 + break;
  155 + case MAX8925_IRQ_VCHG_TMR_FAULT:
  156 + __set_charger(info, 0);
  157 + dev_dbg(chip->dev, "Safe timer is expired\n");
  158 + break;
  159 + case MAX8925_IRQ_VCHG_RST:
  160 + __set_charger(info, 0);
  161 + dev_dbg(chip->dev, "Charger is reset\n");
  162 + break;
  163 + }
  164 + return IRQ_HANDLED;
  165 +}
  166 +
  167 +static int start_measure(struct max8925_power_info *info, int type)
  168 +{
  169 + unsigned char buf[2] = {0, 0};
  170 + int meas_reg = 0, ret;
  171 +
  172 + switch (type) {
  173 + case MEASURE_VCHG:
  174 + meas_reg = MAX8925_ADC_VCHG;
  175 + break;
  176 + case MEASURE_VBBATT:
  177 + meas_reg = MAX8925_ADC_VBBATT;
  178 + break;
  179 + case MEASURE_VMBATT:
  180 + meas_reg = MAX8925_ADC_VMBATT;
  181 + break;
  182 + case MEASURE_ISNS:
  183 + meas_reg = MAX8925_ADC_ISNS;
  184 + break;
  185 + default:
  186 + return -EINVAL;
  187 + }
  188 +
  189 + max8925_bulk_read(info->adc, meas_reg, 2, buf);
  190 + ret = (buf[0] << 4) | (buf[1] >> 4);
  191 +
  192 + return ret;
  193 +}
  194 +
  195 +static int max8925_ac_get_prop(struct power_supply *psy,
  196 + enum power_supply_property psp,
  197 + union power_supply_propval *val)
  198 +{
  199 + struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
  200 + int ret = 0;
  201 +
  202 + switch (psp) {
  203 + case POWER_SUPPLY_PROP_ONLINE:
  204 + val->intval = info->ac_online;
  205 + break;
  206 + case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  207 + if (info->ac_online) {
  208 + ret = start_measure(info, MEASURE_VCHG);
  209 + if (ret >= 0) {
  210 + val->intval = ret << 1; /* unit is mV */
  211 + goto out;
  212 + }
  213 + }
  214 + ret = -ENODATA;
  215 + break;
  216 + default:
  217 + ret = -ENODEV;
  218 + break;
  219 + }
  220 +out:
  221 + return ret;
  222 +}
  223 +
  224 +static enum power_supply_property max8925_ac_props[] = {
  225 + POWER_SUPPLY_PROP_ONLINE,
  226 + POWER_SUPPLY_PROP_VOLTAGE_NOW,
  227 +};
  228 +
  229 +static int max8925_usb_get_prop(struct power_supply *psy,
  230 + enum power_supply_property psp,
  231 + union power_supply_propval *val)
  232 +{
  233 + struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
  234 + int ret = 0;
  235 +
  236 + switch (psp) {
  237 + case POWER_SUPPLY_PROP_ONLINE:
  238 + val->intval = info->usb_online;
  239 + break;
  240 + case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  241 + if (info->usb_online) {
  242 + ret = start_measure(info, MEASURE_VCHG);
  243 + if (ret >= 0) {
  244 + val->intval = ret << 1; /* unit is mV */
  245 + goto out;
  246 + }
  247 + }
  248 + ret = -ENODATA;
  249 + break;
  250 + default:
  251 + ret = -ENODEV;
  252 + break;
  253 + }
  254 +out:
  255 + return ret;
  256 +}
  257 +
  258 +static enum power_supply_property max8925_usb_props[] = {
  259 + POWER_SUPPLY_PROP_ONLINE,
  260 + POWER_SUPPLY_PROP_VOLTAGE_NOW,
  261 +};
  262 +
  263 +static int max8925_bat_get_prop(struct power_supply *psy,
  264 + enum power_supply_property psp,
  265 + union power_supply_propval *val)
  266 +{
  267 + struct max8925_power_info *info = dev_get_drvdata(psy->dev->parent);
  268 + long long int tmp = 0;
  269 + int ret = 0;
  270 +
  271 + switch (psp) {
  272 + case POWER_SUPPLY_PROP_ONLINE:
  273 + val->intval = info->bat_online;
  274 + break;
  275 + case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  276 + if (info->bat_online) {
  277 + ret = start_measure(info, MEASURE_VMBATT);
  278 + if (ret >= 0) {
  279 + val->intval = ret << 1; /* unit is mV */
  280 + ret = 0;
  281 + break;
  282 + }
  283 + }
  284 + ret = -ENODATA;
  285 + break;
  286 + case POWER_SUPPLY_PROP_CURRENT_NOW:
  287 + if (info->bat_online) {
  288 + ret = start_measure(info, MEASURE_ISNS);
  289 + if (ret >= 0) {
  290 + tmp = (long long int)ret * 6250 / 4096 - 3125;
  291 + ret = (int)tmp;
  292 + val->intval = 0;
  293 + if (ret > 0)
  294 + val->intval = ret; /* unit is mA */
  295 + ret = 0;
  296 + break;
  297 + }
  298 + }
  299 + ret = -ENODATA;
  300 + break;
  301 + case POWER_SUPPLY_PROP_CHARGE_TYPE:
  302 + if (!info->bat_online) {
  303 + ret = -ENODATA;
  304 + break;
  305 + }
  306 + ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
  307 + ret = (ret & MAX8925_CHG_STAT_MODE_MASK) >> 2;
  308 + switch (ret) {
  309 + case 1:
  310 + val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
  311 + break;
  312 + case 0:
  313 + case 2:
  314 + val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
  315 + break;
  316 + case 3:
  317 + val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
  318 + break;
  319 + }
  320 + ret = 0;
  321 + break;
  322 + case POWER_SUPPLY_PROP_STATUS:
  323 + if (!info->bat_online) {
  324 + ret = -ENODATA;
  325 + break;
  326 + }
  327 + ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
  328 + if (info->usb_online || info->ac_online) {
  329 + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
  330 + if (ret & MAX8925_CHG_STAT_EN_MASK)
  331 + val->intval = POWER_SUPPLY_STATUS_CHARGING;
  332 + } else
  333 + val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
  334 + ret = 0;
  335 + break;
  336 + default:
  337 + ret = -ENODEV;
  338 + break;
  339 + }
  340 + return ret;
  341 +}
  342 +
  343 +static enum power_supply_property max8925_battery_props[] = {
  344 + POWER_SUPPLY_PROP_ONLINE,
  345 + POWER_SUPPLY_PROP_VOLTAGE_NOW,
  346 + POWER_SUPPLY_PROP_CURRENT_NOW,
  347 + POWER_SUPPLY_PROP_CHARGE_TYPE,
  348 + POWER_SUPPLY_PROP_STATUS,
  349 +};
  350 +
  351 +#define REQUEST_IRQ(_irq, _name) \
  352 +do { \
  353 + ret = request_threaded_irq(chip->irq_base + _irq, NULL, \
  354 + max8925_charger_handler, \
  355 + IRQF_ONESHOT, _name, info); \
  356 + if (ret) \
  357 + dev_err(chip->dev, "Failed to request IRQ #%d: %d\n", \
  358 + _irq, ret); \
  359 +} while (0)
  360 +
  361 +static __devinit int max8925_init_charger(struct max8925_chip *chip,
  362 + struct max8925_power_info *info)
  363 +{
  364 + int ret;
  365 +
  366 + REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_OVP, "ac-ovp");
  367 + REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_F, "ac-remove");
  368 + REQUEST_IRQ(MAX8925_IRQ_VCHG_DC_R, "ac-insert");
  369 + REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_OVP, "usb-ovp");
  370 + REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_F, "usb-remove");
  371 + REQUEST_IRQ(MAX8925_IRQ_VCHG_USB_R, "usb-insert");
  372 + REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_R, "batt-temp-in-range");
  373 + REQUEST_IRQ(MAX8925_IRQ_VCHG_THM_OK_F, "batt-temp-out-range");
  374 + REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_F, "vsys-high");
  375 + REQUEST_IRQ(MAX8925_IRQ_VCHG_SYSLOW_R, "vsys-low");
  376 + REQUEST_IRQ(MAX8925_IRQ_VCHG_RST, "charger-reset");
  377 + REQUEST_IRQ(MAX8925_IRQ_VCHG_DONE, "charger-done");
  378 + REQUEST_IRQ(MAX8925_IRQ_VCHG_TOPOFF, "charger-topoff");
  379 + REQUEST_IRQ(MAX8925_IRQ_VCHG_TMR_FAULT, "charger-timer-expire");
  380 +
  381 + info->ac_online = 0;
  382 + info->usb_online = 0;
  383 + info->bat_online = 0;
  384 + ret = max8925_reg_read(info->gpm, MAX8925_CHG_STATUS);
  385 + if (ret >= 0) {
  386 + /*
  387 + * If battery detection is enabled, ID pin of battery is
  388 + * connected to MBDET pin of MAX8925. It could be used to
  389 + * detect battery presence.
  390 + * Otherwise, we have to assume that battery is always on.
  391 + */
  392 + if (info->batt_detect)
  393 + info->bat_online = (ret & MAX8925_CHG_MBDET) ? 0 : 1;
  394 + else
  395 + info->bat_online = 1;
  396 + if (ret & MAX8925_CHG_AC_RANGE_MASK)
  397 + info->ac_online = 1;
  398 + else
  399 + info->ac_online = 0;
  400 + }
  401 + /* disable charge */
  402 + max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 1 << 7, 1 << 7);
  403 + /* set charging current in charge topoff mode */
  404 + max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 3 << 5,
  405 + info->topoff_threshold << 5);
  406 + /* set charing current in fast charge mode */
  407 + max8925_set_bits(info->gpm, MAX8925_CHG_CNTL1, 7, info->fast_charge);
  408 +
  409 + return 0;
  410 +}
  411 +
  412 +static __devexit int max8925_deinit_charger(struct max8925_power_info *info)
  413 +{
  414 + struct max8925_chip *chip = info->chip;
  415 + int irq;
  416 +
  417 + irq = chip->irq_base + MAX8925_IRQ_VCHG_DC_OVP;
  418 + for (; irq <= chip->irq_base + MAX8925_IRQ_VCHG_TMR_FAULT; irq++)
  419 + free_irq(irq, info);
  420 +
  421 + return 0;
  422 +}
  423 +
  424 +static __devinit int max8925_power_probe(struct platform_device *pdev)
  425 +{
  426 + struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
  427 + struct max8925_platform_data *max8925_pdata;
  428 + struct max8925_power_pdata *pdata = NULL;
  429 + struct max8925_power_info *info;
  430 + int ret;
  431 +
  432 + if (pdev->dev.parent->platform_data) {
  433 + max8925_pdata = pdev->dev.parent->platform_data;
  434 + pdata = max8925_pdata->power;
  435 + }
  436 +
  437 + if (!pdata) {
  438 + dev_err(&pdev->dev, "platform data isn't assigned to "
  439 + "power supply\n");
  440 + return -EINVAL;
  441 + }
  442 +
  443 + info = kzalloc(sizeof(struct max8925_power_info), GFP_KERNEL);
  444 + if (!info)
  445 + return -ENOMEM;
  446 + info->chip = chip;
  447 + info->gpm = chip->i2c;
  448 + info->adc = chip->adc;
  449 +
  450 + info->ac.name = "max8925-ac";
  451 + info->ac.type = POWER_SUPPLY_TYPE_MAINS;
  452 + info->ac.properties = max8925_ac_props;
  453 + info->ac.num_properties = ARRAY_SIZE(max8925_ac_props);
  454 + info->ac.get_property = max8925_ac_get_prop;
  455 + ret = power_supply_register(&pdev->dev, &info->ac);
  456 + if (ret)
  457 + goto out;
  458 + info->ac.dev->parent = &pdev->dev;
  459 +
  460 + info->usb.name = "max8925-usb";
  461 + info->usb.type = POWER_SUPPLY_TYPE_USB;
  462 + info->usb.properties = max8925_usb_props;
  463 + info->usb.num_properties = ARRAY_SIZE(max8925_usb_props);
  464 + info->usb.get_property = max8925_usb_get_prop;
  465 + ret = power_supply_register(&pdev->dev, &info->usb);
  466 + if (ret)
  467 + goto out_usb;
  468 + info->usb.dev->parent = &pdev->dev;
  469 +
  470 + info->battery.name = "max8925-battery";
  471 + info->battery.type = POWER_SUPPLY_TYPE_BATTERY;
  472 + info->battery.properties = max8925_battery_props;
  473 + info->battery.num_properties = ARRAY_SIZE(max8925_battery_props);
  474 + info->battery.get_property = max8925_bat_get_prop;
  475 + ret = power_supply_register(&pdev->dev, &info->battery);
  476 + if (ret)
  477 + goto out_battery;
  478 + info->battery.dev->parent = &pdev->dev;
  479 +
  480 + info->batt_detect = pdata->batt_detect;
  481 + info->topoff_threshold = pdata->topoff_threshold;
  482 + info->fast_charge = pdata->fast_charge;
  483 + info->set_charger = pdata->set_charger;
  484 + dev_set_drvdata(&pdev->dev, info);
  485 + platform_set_drvdata(pdev, info);
  486 +
  487 + max8925_init_charger(chip, info);
  488 + return 0;
  489 +out_battery:
  490 + power_supply_unregister(&info->battery);
  491 +out_usb:
  492 + power_supply_unregister(&info->ac);
  493 +out:
  494 + kfree(info);
  495 + return ret;
  496 +}
  497 +
  498 +static __devexit int max8925_power_remove(struct platform_device *pdev)
  499 +{
  500 + struct max8925_power_info *info = platform_get_drvdata(pdev);
  501 +
  502 + if (info) {
  503 + power_supply_unregister(&info->ac);
  504 + power_supply_unregister(&info->usb);
  505 + power_supply_unregister(&info->battery);
  506 + max8925_deinit_charger(info);
  507 + kfree(info);
  508 + }
  509 + return 0;
  510 +}
  511 +
  512 +static struct platform_driver max8925_power_driver = {
  513 + .probe = max8925_power_probe,
  514 + .remove = __devexit_p(max8925_power_remove),
  515 + .driver = {
  516 + .name = "max8925-power",
  517 + },
  518 +};
  519 +
  520 +static int __init max8925_power_init(void)
  521 +{
  522 + return platform_driver_register(&max8925_power_driver);
  523 +}
  524 +module_init(max8925_power_init);
  525 +
  526 +static void __exit max8925_power_exit(void)
  527 +{
  528 + platform_driver_unregister(&max8925_power_driver);
  529 +}
  530 +module_exit(max8925_power_exit);
  531 +
  532 +MODULE_LICENSE("GPL");
  533 +MODULE_DESCRIPTION("Power supply driver for MAX8925");
  534 +MODULE_ALIAS("platform:max8925-power");