Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (pmbus) Add regulator support

Add support for simple on/off control of each channel.

To add regulator support, the pmbus part driver needs to add
regulator_desc information and number of regulators to its
pmbus_driver_info struct.

regulator_desc can be declared using default macro for a
regulator (PMBUS_REGULATOR) that is in pmbus.h

The regulator_init_data can be initialized from either
platform data or the device tree.

Signed-off-by: Alan Tull <atull@opensource.altera.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>

authored by

Alan Tull and committed by
Guenter Roeck
ddbb4db4 11c11998

+117
+26
drivers/hwmon/pmbus/pmbus.h
··· 19 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 20 */ 21 21 22 + #include <linux/regulator/driver.h> 23 + 22 24 #ifndef PMBUS_H 23 25 #define PMBUS_H 24 26 ··· 186 184 #define PMBUS_VIRT_VMON_UV_FAULT_LIMIT (PMBUS_VIRT_BASE + 33) 187 185 #define PMBUS_VIRT_VMON_OV_FAULT_LIMIT (PMBUS_VIRT_BASE + 34) 188 186 #define PMBUS_VIRT_STATUS_VMON (PMBUS_VIRT_BASE + 35) 187 + 188 + /* 189 + * OPERATION 190 + */ 191 + #define PB_OPERATION_CONTROL_ON (1<<7) 189 192 190 193 /* 191 194 * CAPABILITY ··· 372 365 */ 373 366 int (*identify)(struct i2c_client *client, 374 367 struct pmbus_driver_info *info); 368 + 369 + /* Regulator functionality, if supported by this chip driver. */ 370 + int num_regulators; 371 + const struct regulator_desc *reg_desc; 375 372 }; 373 + 374 + /* Regulator ops */ 375 + 376 + extern struct regulator_ops pmbus_regulator_ops; 377 + 378 + /* Macro for filling in array of struct regulator_desc */ 379 + #define PMBUS_REGULATOR(_name, _id) \ 380 + [_id] = { \ 381 + .name = (_name # _id), \ 382 + .id = (_id), \ 383 + .of_match = of_match_ptr(_name # _id), \ 384 + .regulators_node = of_match_ptr("regulators"), \ 385 + .ops = &pmbus_regulator_ops, \ 386 + .owner = THIS_MODULE, \ 387 + } 376 388 377 389 /* Function declarations */ 378 390
+87
drivers/hwmon/pmbus/pmbus_core.c
··· 29 29 #include <linux/hwmon-sysfs.h> 30 30 #include <linux/jiffies.h> 31 31 #include <linux/i2c/pmbus.h> 32 + #include <linux/regulator/driver.h> 33 + #include <linux/regulator/machine.h> 32 34 #include "pmbus.h" 33 35 34 36 /* ··· 1760 1758 return 0; 1761 1759 } 1762 1760 1761 + #if IS_ENABLED(CONFIG_REGULATOR) 1762 + static int pmbus_regulator_is_enabled(struct regulator_dev *rdev) 1763 + { 1764 + struct device *dev = rdev_get_dev(rdev); 1765 + struct i2c_client *client = to_i2c_client(dev->parent); 1766 + u8 page = rdev_get_id(rdev); 1767 + int ret; 1768 + 1769 + ret = pmbus_read_byte_data(client, page, PMBUS_OPERATION); 1770 + if (ret < 0) 1771 + return ret; 1772 + 1773 + return !!(ret & PB_OPERATION_CONTROL_ON); 1774 + } 1775 + 1776 + static int _pmbus_regulator_on_off(struct regulator_dev *rdev, bool enable) 1777 + { 1778 + struct device *dev = rdev_get_dev(rdev); 1779 + struct i2c_client *client = to_i2c_client(dev->parent); 1780 + u8 page = rdev_get_id(rdev); 1781 + 1782 + return pmbus_update_byte_data(client, page, PMBUS_OPERATION, 1783 + PB_OPERATION_CONTROL_ON, 1784 + enable ? PB_OPERATION_CONTROL_ON : 0); 1785 + } 1786 + 1787 + static int pmbus_regulator_enable(struct regulator_dev *rdev) 1788 + { 1789 + return _pmbus_regulator_on_off(rdev, 1); 1790 + } 1791 + 1792 + static int pmbus_regulator_disable(struct regulator_dev *rdev) 1793 + { 1794 + return _pmbus_regulator_on_off(rdev, 0); 1795 + } 1796 + 1797 + struct regulator_ops pmbus_regulator_ops = { 1798 + .enable = pmbus_regulator_enable, 1799 + .disable = pmbus_regulator_disable, 1800 + .is_enabled = pmbus_regulator_is_enabled, 1801 + }; 1802 + EXPORT_SYMBOL_GPL(pmbus_regulator_ops); 1803 + 1804 + static int pmbus_regulator_register(struct pmbus_data *data) 1805 + { 1806 + struct device *dev = data->dev; 1807 + const struct pmbus_driver_info *info = data->info; 1808 + const struct pmbus_platform_data *pdata = dev_get_platdata(dev); 1809 + struct regulator_dev *rdev; 1810 + int i; 1811 + 1812 + for (i = 0; i < info->num_regulators; i++) { 1813 + struct regulator_config config = { }; 1814 + 1815 + config.dev = dev; 1816 + config.driver_data = data; 1817 + 1818 + if (pdata && pdata->reg_init_data) 1819 + config.init_data = &pdata->reg_init_data[i]; 1820 + 1821 + rdev = devm_regulator_register(dev, &info->reg_desc[i], 1822 + &config); 1823 + if (IS_ERR(rdev)) { 1824 + dev_err(dev, "Failed to register %s regulator\n", 1825 + info->reg_desc[i].name); 1826 + return PTR_ERR(rdev); 1827 + } 1828 + } 1829 + 1830 + return 0; 1831 + } 1832 + #else 1833 + static int pmbus_regulator_register(struct pmbus_data *data) 1834 + { 1835 + return 0; 1836 + } 1837 + #endif 1838 + 1763 1839 int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, 1764 1840 struct pmbus_driver_info *info) 1765 1841 { ··· 1892 1812 dev_err(dev, "Failed to register hwmon device\n"); 1893 1813 goto out_kfree; 1894 1814 } 1815 + 1816 + ret = pmbus_regulator_register(data); 1817 + if (ret) 1818 + goto out_unregister; 1819 + 1895 1820 return 0; 1896 1821 1822 + out_unregister: 1823 + hwmon_device_unregister(data->hwmon_dev); 1897 1824 out_kfree: 1898 1825 kfree(data->group.attrs); 1899 1826 return ret;
+4
include/linux/i2c/pmbus.h
··· 40 40 41 41 struct pmbus_platform_data { 42 42 u32 flags; /* Device specific flags */ 43 + 44 + /* regulator support */ 45 + int num_regulators; 46 + struct regulator_init_data *reg_init_data; 43 47 }; 44 48 45 49 #endif /* _PMBUS_H_ */