Tom Rini | 83d290c | 2018-05-06 17:58:06 -0400 | [diff] [blame^] | 1 | // SPDX-License-Identifier: GPL-2.0+ |
Łukasz Majewski | e542b7f | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 2 | /* |
| 3 | * Copyright (C) 2011 Samsung Electronics |
| 4 | * Lukasz Majewski <l.majewski@samsung.com> |
| 5 | * |
| 6 | * (C) Copyright 2010 |
| 7 | * Stefano Babic, DENX Software Engineering, sbabic@denx.de |
| 8 | * |
| 9 | * (C) Copyright 2008-2009 Freescale Semiconductor, Inc. |
Łukasz Majewski | e542b7f | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 10 | */ |
| 11 | |
| 12 | #include <common.h> |
| 13 | #include <linux/types.h> |
Łukasz Majewski | c733681 | 2012-11-13 03:21:55 +0000 | [diff] [blame] | 14 | #include <power/pmic.h> |
Łukasz Majewski | e542b7f | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 15 | #include <spi.h> |
| 16 | |
| 17 | static struct spi_slave *slave; |
| 18 | |
Łukasz Majewski | e542b7f | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 19 | static u32 pmic_reg(struct pmic *p, u32 reg, u32 *val, u32 write) |
| 20 | { |
| 21 | u32 pmic_tx, pmic_rx; |
| 22 | u32 tmp; |
| 23 | |
| 24 | if (!slave) { |
Tom Rini | 5b471de | 2014-10-25 07:38:31 -0400 | [diff] [blame] | 25 | slave = spi_setup_slave(p->bus, p->hw.spi.cs, p->hw.spi.clk, |
| 26 | p->hw.spi.mode); |
Łukasz Majewski | e542b7f | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 27 | |
| 28 | if (!slave) |
Jaehoon Chung | 505cf47 | 2016-12-15 20:49:50 +0900 | [diff] [blame] | 29 | return -ENODEV; |
Łukasz Majewski | e542b7f | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 30 | } |
| 31 | |
Łukasz Majewski | c733681 | 2012-11-13 03:21:55 +0000 | [diff] [blame] | 32 | if (check_reg(p, reg)) |
Jaehoon Chung | 505cf47 | 2016-12-15 20:49:50 +0900 | [diff] [blame] | 33 | return -EINVAL; |
Łukasz Majewski | e542b7f | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 34 | |
| 35 | if (spi_claim_bus(slave)) |
Jaehoon Chung | 505cf47 | 2016-12-15 20:49:50 +0900 | [diff] [blame] | 36 | return -EBUSY; |
Łukasz Majewski | e542b7f | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 37 | |
| 38 | pmic_tx = p->hw.spi.prepare_tx(reg, val, write); |
| 39 | |
| 40 | tmp = cpu_to_be32(pmic_tx); |
| 41 | |
| 42 | if (spi_xfer(slave, pmic_spi_bitlen, &tmp, &pmic_rx, |
Tom Rini | 5b471de | 2014-10-25 07:38:31 -0400 | [diff] [blame] | 43 | pmic_spi_flags)) |
| 44 | goto err; |
Łukasz Majewski | e542b7f | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 45 | |
| 46 | if (write) { |
Helmut Raiger | 435a728 | 2011-10-19 20:34:43 +0000 | [diff] [blame] | 47 | pmic_tx = p->hw.spi.prepare_tx(reg, val, 0); |
Łukasz Majewski | e542b7f | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 48 | tmp = cpu_to_be32(pmic_tx); |
| 49 | if (spi_xfer(slave, pmic_spi_bitlen, &tmp, &pmic_rx, |
Tom Rini | 5b471de | 2014-10-25 07:38:31 -0400 | [diff] [blame] | 50 | pmic_spi_flags)) |
| 51 | goto err; |
Łukasz Majewski | e542b7f | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 52 | } |
| 53 | |
| 54 | spi_release_bus(slave); |
| 55 | *val = cpu_to_be32(pmic_rx); |
| 56 | |
| 57 | return 0; |
Tom Rini | 5b471de | 2014-10-25 07:38:31 -0400 | [diff] [blame] | 58 | |
| 59 | err: |
| 60 | spi_release_bus(slave); |
Jaehoon Chung | 505cf47 | 2016-12-15 20:49:50 +0900 | [diff] [blame] | 61 | return -ENOTSUPP; |
Łukasz Majewski | e542b7f | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 62 | } |
| 63 | |
| 64 | int pmic_reg_write(struct pmic *p, u32 reg, u32 val) |
| 65 | { |
Jaehoon Chung | 505cf47 | 2016-12-15 20:49:50 +0900 | [diff] [blame] | 66 | return pmic_reg(p, reg, &val, 1); |
Łukasz Majewski | e542b7f | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 67 | } |
| 68 | |
| 69 | int pmic_reg_read(struct pmic *p, u32 reg, u32 *val) |
| 70 | { |
Jaehoon Chung | 505cf47 | 2016-12-15 20:49:50 +0900 | [diff] [blame] | 71 | return pmic_reg(p, reg, val, 0); |
Łukasz Majewski | e542b7f | 2011-10-06 02:37:34 +0000 | [diff] [blame] | 72 | } |