uboot/drivers/power/pmic/mc34708.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2018
   4 * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
   5 *
   6 */
   7
   8#include <common.h>
   9#include <dm.h>
  10#include <errno.h>
  11#include <fsl_pmic.h>
  12#include <i2c.h>
  13#include <asm/global_data.h>
  14#include <power/pmic.h>
  15
  16DECLARE_GLOBAL_DATA_PTR;
  17
  18static int mc34708_reg_count(struct udevice *dev)
  19{
  20        return PMIC_NUM_OF_REGS;
  21}
  22
  23static int mc34708_write(struct udevice *dev, uint reg, const u8 *buff,
  24                         int len)
  25{
  26        u8 buf[3] = { 0 };
  27        int ret;
  28
  29        if (len != MC34708_TRANSFER_SIZE)
  30                return -EINVAL;
  31
  32        /*
  33         * The MC34708 sends data with big endian format, hence we need to
  34         * perform manual byte swap.
  35         */
  36        buf[0] = buff[2];
  37        buf[1] = buff[1];
  38        buf[2] = buff[0];
  39
  40        ret = dm_i2c_write(dev, reg, buf, len);
  41        if (ret)
  42                printf("write error to device: %p register: %#x!\n", dev, reg);
  43
  44        return ret;
  45}
  46
  47static int mc34708_read(struct udevice *dev, uint reg, u8 *buff, int len)
  48{
  49        u8 buf[3] = { 0 };
  50        int ret;
  51
  52        if (len != MC34708_TRANSFER_SIZE)
  53                return -EINVAL;
  54
  55        ret = dm_i2c_read(dev, reg, buf, len);
  56        if (ret)
  57                printf("read error from device: %p register: %#x!\n", dev, reg);
  58
  59        buff[0] = buf[2];
  60        buff[1] = buf[1];
  61        buff[2] = buf[0];
  62
  63        return ret;
  64}
  65
  66static int mc34708_probe(struct udevice *dev)
  67{
  68        struct uc_pmic_priv *priv = dev_get_uclass_priv(dev);
  69
  70        priv->trans_len = MC34708_TRANSFER_SIZE;
  71
  72        /*
  73         * Handle PMIC Errata 37: APS mode not fully functional,
  74         * use explicit PWM or PFM instead
  75         */
  76        pmic_clrsetbits(dev, MC34708_REG_SW12_OPMODE,
  77                        MC34708_SW1AMODE_MASK | MC34708_SW2MODE_MASK,
  78                        SW_MODE_PWMPWM | (SW_MODE_PWMPWM << 14u));
  79
  80        pmic_clrsetbits(dev, MC34708_REG_SW345_OPMODE,
  81                        MC34708_SW3MODE_MASK | MC34708_SW4AMODE_MASK |
  82                        MC34708_SW4BMODE_MASK | MC34708_SW5MODE_MASK,
  83                        SW_MODE_PWMPWM | (SW_MODE_PWMPWM << 6u) |
  84                        (SW_MODE_PWMPWM << 12u) | (SW_MODE_PWMPWM << 18u));
  85
  86        return 0;
  87}
  88
  89static struct dm_pmic_ops mc34708_ops = {
  90        .reg_count = mc34708_reg_count,
  91        .read   = mc34708_read,
  92        .write  = mc34708_write,
  93};
  94
  95static const struct udevice_id mc34708_ids[] = {
  96        { .compatible = "fsl,mc34708" },
  97        { }
  98};
  99
 100U_BOOT_DRIVER(pmic_mc34708) = {
 101        .name           = "mc34708_pmic",
 102        .id             = UCLASS_PMIC,
 103        .of_match       = mc34708_ids,
 104        .probe          = mc34708_probe,
 105        .ops            = &mc34708_ops,
 106};
 107