summaryrefslogtreecommitdiff
path: root/bsp/allwinner/libraries/sunxi-hal/hal/source/regulator/axp_twi.c
blob: 05756b374628aae4ed17181b17fbefee10c0c376 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
 * Copyright (C) 2020 allwinnertech Ltd.
 */

#include <log.h>
#include <sunxi_hal_regulator.h>
#include <sunxi_hal_regulator_private.h>
#include <sunxi_hal_twi.h>

int hal_axp_twi_init(struct regulator_dev *rdev)
{
    unsigned char port = TWI_PORT(rdev->flag);
    unsigned short addr = AXP_ADDR(rdev->flag);

    hal_twi_init(port);
    hal_twi_control(port, I2C_SLAVE, &addr);

    return 0;
}

int hal_axp_byte_read(struct regulator_dev *rdev, u8 reg, u8 *reg_val)
{
    unsigned char port = TWI_PORT(rdev->flag);
    int ret;

    ret = hal_twi_read(port, reg, reg_val, 1);
    if (ret > 0)
        return 0;

    return ret;
}

int hal_axp_byte_write(struct regulator_dev *rdev, u8 reg, u8 reg_val)
{
    /* hal_twi_write bug workaround */
    unsigned char port = TWI_PORT(rdev->flag);
    twi_msg_t msg;
    uint8_t buf[2];

    buf[0] = reg;
    buf[1] = reg_val;
    msg.flags = 0;
    msg.addr = AXP_ADDR(rdev->flag);
    msg.len = 2;
    msg.buf = buf;

    return hal_twi_control(port, I2C_RDWR, &msg);
}

int hal_axp_byte_update(struct regulator_dev *rdev, u8 reg, u8 val, u8 mask)
{
    u8 reg_val = 0;
    int ret = 0;

    ret = hal_axp_byte_read(rdev, reg, &reg_val);
    if (ret)
        goto out;

    if ((reg_val & mask) != val) {
        reg_val = (reg_val & ~mask) | (val & mask);
        ret = hal_axp_byte_write(rdev, reg, reg_val);
    }

out:
    return ret;
}