Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/wgpu-hal/   (Apache Software Stiftung Version 2.4.65©)  Datei vom 10.2.2025 mit Größe 9 kB image not shown  

Quelle  ad5398.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Voltage and current regulation for AD5398 and AD5821
 *
 * Copyright 2010 Analog Devices Inc.
 *
 * Enter bugs at http://blackfin.uclinux.org/
 */


#include <linux/module.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>

#define AD5398_SW_POWER_DOWN BIT(15)

struct ad5398_chip_info {
 struct i2c_client *client;
 int min_uA;
 int max_uA;
 unsigned int current_level;
 unsigned int current_mask;
 unsigned int current_offset;
 struct regulator_dev *rdev;
};

static int ad5398_calc_current(struct ad5398_chip_info *chip,
 unsigned selector)
{
 unsigned range_uA = chip->max_uA - chip->min_uA;

 return chip->min_uA + (selector * range_uA / chip->current_level);
}

static int ad5398_read_reg(struct i2c_client *client, unsigned short *data)
{
 unsigned short val;
 int ret;

 ret = i2c_master_recv(client, (char *)&val, 2);
 if (ret < 0) {
  dev_err(&client->dev, "I2C read error\n");
  return ret;
 }
 *data = be16_to_cpu(val);

 return ret;
}

static int ad5398_write_reg(struct i2c_client *client, const unsigned short data)
{
 unsigned short val;
 int ret;

 val = cpu_to_be16(data);
 ret = i2c_master_send(client, (char *)&val, 2);
 if (ret != 2) {
  dev_err(&client->dev, "I2C write error\n");
  return ret < 0 ? ret : -EIO;
 }

 return 0;
}

static int ad5398_get_current_limit(struct regulator_dev *rdev)
{
 struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
 struct i2c_client *client = chip->client;
 unsigned short data;
 int ret;

 ret = ad5398_read_reg(client, &data);
 if (ret < 0)
  return ret;

 ret = (data & chip->current_mask) >> chip->current_offset;

 return ad5398_calc_current(chip, ret);
}

static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA)
{
 struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
 struct i2c_client *client = chip->client;
 unsigned range_uA = chip->max_uA - chip->min_uA;
 unsigned selector;
 unsigned short data;
 int ret;

 if (min_uA < chip->min_uA)
  min_uA = chip->min_uA;
 if (max_uA > chip->max_uA)
  max_uA = chip->max_uA;

 if (min_uA > chip->max_uA || max_uA < chip->min_uA)
  return -EINVAL;

 selector = DIV_ROUND_UP((min_uA - chip->min_uA) * chip->current_level,
    range_uA);
 if (ad5398_calc_current(chip, selector) > max_uA)
  return -EINVAL;

 dev_dbg(&client->dev, "changing current %duA\n",
  ad5398_calc_current(chip, selector));

 /* read chip enable bit */
 ret = ad5398_read_reg(client, &data);
 if (ret < 0)
  return ret;

 /* prepare register data */
 selector = (selector << chip->current_offset) & chip->current_mask;
 data = (unsigned short)selector | (data & AD5398_SW_POWER_DOWN);

 /* write the new current value back as well as enable bit */
 ret = ad5398_write_reg(client, data);

 return ret;
}

static int ad5398_is_enabled(struct regulator_dev *rdev)
{
 struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
 struct i2c_client *client = chip->client;
 unsigned short data;
 int ret;

 ret = ad5398_read_reg(client, &data);
 if (ret < 0)
  return ret;

 if (data & AD5398_SW_POWER_DOWN)
  return 0;
 else
  return 1;
}

static int ad5398_enable(struct regulator_dev *rdev)
{
 struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
 struct i2c_client *client = chip->client;
 unsigned short data;
 int ret;

 ret = ad5398_read_reg(client, &data);
 if (ret < 0)
  return ret;

 if (!(data & AD5398_SW_POWER_DOWN))
  return 0;

 data &= ~AD5398_SW_POWER_DOWN;

 ret = ad5398_write_reg(client, data);

 return ret;
}

static int ad5398_disable(struct regulator_dev *rdev)
{
 struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
 struct i2c_client *client = chip->client;
 unsigned short data;
 int ret;

 ret = ad5398_read_reg(client, &data);
 if (ret < 0)
  return ret;

 if (data & AD5398_SW_POWER_DOWN)
  return 0;

 data |= AD5398_SW_POWER_DOWN;

 ret = ad5398_write_reg(client, data);

 return ret;
}

static const struct regulator_ops ad5398_ops = {
 .get_current_limit = ad5398_get_current_limit,
 .set_current_limit = ad5398_set_current_limit,
 .enable = ad5398_enable,
 .disable = ad5398_disable,
 .is_enabled = ad5398_is_enabled,
};

static const struct regulator_desc ad5398_reg = {
 .name = "isink",
 .id = 0,
 .ops = &ad5398_ops,
 .type = REGULATOR_CURRENT,
 .owner = THIS_MODULE,
};

struct ad5398_current_data_format {
 int current_bits;
 int current_offset;
 int min_uA;
 int max_uA;
};

static const struct ad5398_current_data_format df_10_4_120 = {10, 4, 0, 120000};

static const struct i2c_device_id ad5398_id[] = {
 { "ad5398", (kernel_ulong_t)&df_10_4_120 },
 { "ad5821", (kernel_ulong_t)&df_10_4_120 },
 { }
};
MODULE_DEVICE_TABLE(i2c, ad5398_id);

static int ad5398_probe(struct i2c_client *client)
{
 const struct i2c_device_id *id = i2c_client_get_device_id(client);
 struct regulator_init_data *init_data = dev_get_platdata(&client->dev);
 struct regulator_config config = { };
 struct ad5398_chip_info *chip;
 const struct ad5398_current_data_format *df =
   (struct ad5398_current_data_format *)id->driver_data;

 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
 if (!chip)
  return -ENOMEM;

 config.dev = &client->dev;
 if (client->dev.of_node)
  init_data = of_get_regulator_init_data(&client->dev,
             client->dev.of_node,
             &ad5398_reg);
 if (!init_data)
  return -EINVAL;

 config.init_data = init_data;
 config.of_node = client->dev.of_node;
 config.driver_data = chip;

 chip->client = client;

 chip->min_uA = df->min_uA;
 chip->max_uA = df->max_uA;
 chip->current_level = 1 << df->current_bits;
 chip->current_offset = df->current_offset;
 chip->current_mask = (chip->current_level - 1) << chip->current_offset;

 chip->rdev = devm_regulator_register(&client->dev, &ad5398_reg,
          &config);
 if (IS_ERR(chip->rdev)) {
  dev_err(&client->dev, "failed to register %s %s\n",
   id->name, ad5398_reg.name);
  return PTR_ERR(chip->rdev);
 }

 i2c_set_clientdata(client, chip);
 dev_dbg(&client->dev, "%s regulator driver is registered.\n", id->name);
 return 0;
}

static struct i2c_driver ad5398_driver = {
 .probe = ad5398_probe,
 .driver  = {
  .name = "ad5398",
  .probe_type = PROBE_PREFER_ASYNCHRONOUS,
 },
 .id_table = ad5398_id,
};

static int __init ad5398_init(void)
{
 return i2c_add_driver(&ad5398_driver);
}
subsys_initcall(ad5398_init);

static void __exit ad5398_exit(void)
{
 i2c_del_driver(&ad5398_driver);
}
module_exit(ad5398_exit);

MODULE_DESCRIPTION("AD5398 and AD5821 current regulator driver");
MODULE_AUTHOR("Sonic Zhang");
MODULE_LICENSE("GPL");

Messung V0.5
C=98 H=100 G=98

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Versionsinformation zu Columbo

Bemerkung:

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Anfrage:

Dauer der Verarbeitung:

Sekunden

sprechenden Kalenders