1a2f9fbc2SHans de Goede // SPDX-License-Identifier: GPL-2.0 2a2f9fbc2SHans de Goede /* Author: Dan Scally <djrscally@gmail.com> */ 3a2f9fbc2SHans de Goede 4a2f9fbc2SHans de Goede #include <linux/acpi.h> 5a2f9fbc2SHans de Goede #include <linux/clkdev.h> 6a2f9fbc2SHans de Goede #include <linux/clk-provider.h> 7a2f9fbc2SHans de Goede #include <linux/device.h> 8a2f9fbc2SHans de Goede #include <linux/gpio/consumer.h> 9a2f9fbc2SHans de Goede #include <linux/regulator/driver.h> 10a2f9fbc2SHans de Goede #include <linux/slab.h> 11a2f9fbc2SHans de Goede 12a2f9fbc2SHans de Goede #include "common.h" 13a2f9fbc2SHans de Goede 14a2f9fbc2SHans de Goede /* 15a2f9fbc2SHans de Goede * The regulators have to have .ops to be valid, but the only ops we actually 16a2f9fbc2SHans de Goede * support are .enable and .disable which are handled via .ena_gpiod. Pass an 17a2f9fbc2SHans de Goede * empty struct to clear the check without lying about capabilities. 18a2f9fbc2SHans de Goede */ 19a2f9fbc2SHans de Goede static const struct regulator_ops int3472_gpio_regulator_ops; 20a2f9fbc2SHans de Goede 21a2f9fbc2SHans de Goede static int skl_int3472_clk_prepare(struct clk_hw *hw) 22a2f9fbc2SHans de Goede { 23a2f9fbc2SHans de Goede struct int3472_gpio_clock *clk = to_int3472_clk(hw); 24a2f9fbc2SHans de Goede 25a2f9fbc2SHans de Goede gpiod_set_value_cansleep(clk->ena_gpio, 1); 26a2f9fbc2SHans de Goede return 0; 27a2f9fbc2SHans de Goede } 28a2f9fbc2SHans de Goede 29a2f9fbc2SHans de Goede static void skl_int3472_clk_unprepare(struct clk_hw *hw) 30a2f9fbc2SHans de Goede { 31a2f9fbc2SHans de Goede struct int3472_gpio_clock *clk = to_int3472_clk(hw); 32a2f9fbc2SHans de Goede 33a2f9fbc2SHans de Goede gpiod_set_value_cansleep(clk->ena_gpio, 0); 34a2f9fbc2SHans de Goede } 35a2f9fbc2SHans de Goede 36a2f9fbc2SHans de Goede static int skl_int3472_clk_enable(struct clk_hw *hw) 37a2f9fbc2SHans de Goede { 38a2f9fbc2SHans de Goede /* 39a2f9fbc2SHans de Goede * We're just turning a GPIO on to enable the clock, which operation 40a2f9fbc2SHans de Goede * has the potential to sleep. Given .enable() cannot sleep, but 41a2f9fbc2SHans de Goede * .prepare() can, we toggle the GPIO in .prepare() instead. Thus, 42a2f9fbc2SHans de Goede * nothing to do here. 43a2f9fbc2SHans de Goede */ 44a2f9fbc2SHans de Goede return 0; 45a2f9fbc2SHans de Goede } 46a2f9fbc2SHans de Goede 47a2f9fbc2SHans de Goede static void skl_int3472_clk_disable(struct clk_hw *hw) 48a2f9fbc2SHans de Goede { 49a2f9fbc2SHans de Goede /* Likewise, nothing to do here... */ 50a2f9fbc2SHans de Goede } 51a2f9fbc2SHans de Goede 52a2f9fbc2SHans de Goede static unsigned int skl_int3472_get_clk_frequency(struct int3472_discrete_device *int3472) 53a2f9fbc2SHans de Goede { 54a2f9fbc2SHans de Goede union acpi_object *obj; 55a2f9fbc2SHans de Goede unsigned int freq; 56a2f9fbc2SHans de Goede 57a2f9fbc2SHans de Goede obj = skl_int3472_get_acpi_buffer(int3472->sensor, "SSDB"); 58a2f9fbc2SHans de Goede if (IS_ERR(obj)) 59a2f9fbc2SHans de Goede return 0; /* report rate as 0 on error */ 60a2f9fbc2SHans de Goede 61a2f9fbc2SHans de Goede if (obj->buffer.length < CIO2_SENSOR_SSDB_MCLKSPEED_OFFSET + sizeof(u32)) { 62a2f9fbc2SHans de Goede dev_err(int3472->dev, "The buffer is too small\n"); 63a2f9fbc2SHans de Goede kfree(obj); 64a2f9fbc2SHans de Goede return 0; 65a2f9fbc2SHans de Goede } 66a2f9fbc2SHans de Goede 67a2f9fbc2SHans de Goede freq = *(u32 *)(obj->buffer.pointer + CIO2_SENSOR_SSDB_MCLKSPEED_OFFSET); 68a2f9fbc2SHans de Goede 69a2f9fbc2SHans de Goede kfree(obj); 70a2f9fbc2SHans de Goede return freq; 71a2f9fbc2SHans de Goede } 72a2f9fbc2SHans de Goede 73a2f9fbc2SHans de Goede static unsigned long skl_int3472_clk_recalc_rate(struct clk_hw *hw, 74a2f9fbc2SHans de Goede unsigned long parent_rate) 75a2f9fbc2SHans de Goede { 76a2f9fbc2SHans de Goede struct int3472_gpio_clock *clk = to_int3472_clk(hw); 77a2f9fbc2SHans de Goede 78a2f9fbc2SHans de Goede return clk->frequency; 79a2f9fbc2SHans de Goede } 80a2f9fbc2SHans de Goede 81a2f9fbc2SHans de Goede static const struct clk_ops skl_int3472_clock_ops = { 82a2f9fbc2SHans de Goede .prepare = skl_int3472_clk_prepare, 83a2f9fbc2SHans de Goede .unprepare = skl_int3472_clk_unprepare, 84a2f9fbc2SHans de Goede .enable = skl_int3472_clk_enable, 85a2f9fbc2SHans de Goede .disable = skl_int3472_clk_disable, 86a2f9fbc2SHans de Goede .recalc_rate = skl_int3472_clk_recalc_rate, 87a2f9fbc2SHans de Goede }; 88a2f9fbc2SHans de Goede 898cf0e541SHans de Goede int skl_int3472_register_clock(struct int3472_discrete_device *int3472, 907a88de31SHans de Goede struct acpi_resource_gpio *agpio, u32 polarity) 91a2f9fbc2SHans de Goede { 928cf0e541SHans de Goede char *path = agpio->resource_source.string_ptr; 93a2f9fbc2SHans de Goede struct clk_init_data init = { 94a2f9fbc2SHans de Goede .ops = &skl_int3472_clock_ops, 95a2f9fbc2SHans de Goede .flags = CLK_GET_RATE_NOCACHE, 96a2f9fbc2SHans de Goede }; 97a2f9fbc2SHans de Goede int ret; 98a2f9fbc2SHans de Goede 998cf0e541SHans de Goede if (int3472->clock.cl) 1008cf0e541SHans de Goede return -EBUSY; 1018cf0e541SHans de Goede 1028cf0e541SHans de Goede int3472->clock.ena_gpio = acpi_get_and_request_gpiod(path, agpio->pin_table[0], 1038cf0e541SHans de Goede "int3472,clk-enable"); 104*fb109fbaSHao Yao if (IS_ERR(int3472->clock.ena_gpio)) { 105*fb109fbaSHao Yao ret = PTR_ERR(int3472->clock.ena_gpio); 106*fb109fbaSHao Yao int3472->clock.ena_gpio = NULL; 107*fb109fbaSHao Yao return dev_err_probe(int3472->dev, ret, "getting clk-enable GPIO\n"); 108*fb109fbaSHao Yao } 1098cf0e541SHans de Goede 1107a88de31SHans de Goede if (polarity == GPIO_ACTIVE_LOW) 1117a88de31SHans de Goede gpiod_toggle_active_low(int3472->clock.ena_gpio); 1127a88de31SHans de Goede 1138cf0e541SHans de Goede /* Ensure the pin is in output mode and non-active state */ 1148cf0e541SHans de Goede gpiod_direction_output(int3472->clock.ena_gpio, 0); 1158cf0e541SHans de Goede 116a2f9fbc2SHans de Goede init.name = kasprintf(GFP_KERNEL, "%s-clk", 117a2f9fbc2SHans de Goede acpi_dev_name(int3472->adev)); 1188cf0e541SHans de Goede if (!init.name) { 1198cf0e541SHans de Goede ret = -ENOMEM; 1208cf0e541SHans de Goede goto out_put_gpio; 1218cf0e541SHans de Goede } 122a2f9fbc2SHans de Goede 123a2f9fbc2SHans de Goede int3472->clock.frequency = skl_int3472_get_clk_frequency(int3472); 124a2f9fbc2SHans de Goede 125a2f9fbc2SHans de Goede int3472->clock.clk_hw.init = &init; 126a2f9fbc2SHans de Goede int3472->clock.clk = clk_register(&int3472->adev->dev, 127a2f9fbc2SHans de Goede &int3472->clock.clk_hw); 128a2f9fbc2SHans de Goede if (IS_ERR(int3472->clock.clk)) { 129a2f9fbc2SHans de Goede ret = PTR_ERR(int3472->clock.clk); 130a2f9fbc2SHans de Goede goto out_free_init_name; 131a2f9fbc2SHans de Goede } 132a2f9fbc2SHans de Goede 133a2f9fbc2SHans de Goede int3472->clock.cl = clkdev_create(int3472->clock.clk, NULL, 134a2f9fbc2SHans de Goede int3472->sensor_name); 135a2f9fbc2SHans de Goede if (!int3472->clock.cl) { 136a2f9fbc2SHans de Goede ret = -ENOMEM; 137a2f9fbc2SHans de Goede goto err_unregister_clk; 138a2f9fbc2SHans de Goede } 139a2f9fbc2SHans de Goede 140a2f9fbc2SHans de Goede kfree(init.name); 141a2f9fbc2SHans de Goede return 0; 142a2f9fbc2SHans de Goede 143a2f9fbc2SHans de Goede err_unregister_clk: 144a2f9fbc2SHans de Goede clk_unregister(int3472->clock.clk); 145a2f9fbc2SHans de Goede out_free_init_name: 146a2f9fbc2SHans de Goede kfree(init.name); 1478cf0e541SHans de Goede out_put_gpio: 1488cf0e541SHans de Goede gpiod_put(int3472->clock.ena_gpio); 149a2f9fbc2SHans de Goede 150a2f9fbc2SHans de Goede return ret; 151a2f9fbc2SHans de Goede } 152a2f9fbc2SHans de Goede 153a2f9fbc2SHans de Goede void skl_int3472_unregister_clock(struct int3472_discrete_device *int3472) 154a2f9fbc2SHans de Goede { 1558cf0e541SHans de Goede if (!int3472->clock.cl) 1568cf0e541SHans de Goede return; 1578cf0e541SHans de Goede 158a2f9fbc2SHans de Goede clkdev_drop(int3472->clock.cl); 159a2f9fbc2SHans de Goede clk_unregister(int3472->clock.clk); 1608cf0e541SHans de Goede gpiod_put(int3472->clock.ena_gpio); 161a2f9fbc2SHans de Goede } 162a2f9fbc2SHans de Goede 163a2f9fbc2SHans de Goede int skl_int3472_register_regulator(struct int3472_discrete_device *int3472, 164a2f9fbc2SHans de Goede struct acpi_resource_gpio *agpio) 165a2f9fbc2SHans de Goede { 166a2f9fbc2SHans de Goede const struct int3472_sensor_config *sensor_config; 167a2f9fbc2SHans de Goede char *path = agpio->resource_source.string_ptr; 168a2f9fbc2SHans de Goede struct regulator_consumer_supply supply_map; 169a2f9fbc2SHans de Goede struct regulator_init_data init_data = { }; 170a2f9fbc2SHans de Goede struct regulator_config cfg = { }; 171a2f9fbc2SHans de Goede int ret; 172a2f9fbc2SHans de Goede 173a2f9fbc2SHans de Goede sensor_config = int3472->sensor_config; 174a2f9fbc2SHans de Goede if (IS_ERR(sensor_config)) { 175a2f9fbc2SHans de Goede dev_err(int3472->dev, "No sensor module config\n"); 176a2f9fbc2SHans de Goede return PTR_ERR(sensor_config); 177a2f9fbc2SHans de Goede } 178a2f9fbc2SHans de Goede 179a2f9fbc2SHans de Goede if (!sensor_config->supply_map.supply) { 180a2f9fbc2SHans de Goede dev_err(int3472->dev, "No supply name defined\n"); 181a2f9fbc2SHans de Goede return -ENODEV; 182a2f9fbc2SHans de Goede } 183a2f9fbc2SHans de Goede 184a2f9fbc2SHans de Goede init_data.constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS; 185a2f9fbc2SHans de Goede init_data.num_consumer_supplies = 1; 186a2f9fbc2SHans de Goede supply_map = sensor_config->supply_map; 187a2f9fbc2SHans de Goede supply_map.dev_name = int3472->sensor_name; 188a2f9fbc2SHans de Goede init_data.consumer_supplies = &supply_map; 189a2f9fbc2SHans de Goede 190a2f9fbc2SHans de Goede snprintf(int3472->regulator.regulator_name, 191a2f9fbc2SHans de Goede sizeof(int3472->regulator.regulator_name), "%s-regulator", 192a2f9fbc2SHans de Goede acpi_dev_name(int3472->adev)); 193a2f9fbc2SHans de Goede snprintf(int3472->regulator.supply_name, 194a2f9fbc2SHans de Goede GPIO_REGULATOR_SUPPLY_NAME_LENGTH, "supply-0"); 195a2f9fbc2SHans de Goede 196a2f9fbc2SHans de Goede int3472->regulator.rdesc = INT3472_REGULATOR( 197a2f9fbc2SHans de Goede int3472->regulator.regulator_name, 198a2f9fbc2SHans de Goede int3472->regulator.supply_name, 199a2f9fbc2SHans de Goede &int3472_gpio_regulator_ops); 200a2f9fbc2SHans de Goede 201a2f9fbc2SHans de Goede int3472->regulator.gpio = acpi_get_and_request_gpiod(path, agpio->pin_table[0], 202a2f9fbc2SHans de Goede "int3472,regulator"); 203a2f9fbc2SHans de Goede if (IS_ERR(int3472->regulator.gpio)) { 204*fb109fbaSHao Yao ret = PTR_ERR(int3472->regulator.gpio); 205*fb109fbaSHao Yao int3472->regulator.gpio = NULL; 206*fb109fbaSHao Yao return dev_err_probe(int3472->dev, ret, "getting regulator GPIO\n"); 207a2f9fbc2SHans de Goede } 208a2f9fbc2SHans de Goede 209cf5ac2d4SHans de Goede /* Ensure the pin is in output mode and non-active state */ 210cf5ac2d4SHans de Goede gpiod_direction_output(int3472->regulator.gpio, 0); 211cf5ac2d4SHans de Goede 212a2f9fbc2SHans de Goede cfg.dev = &int3472->adev->dev; 213a2f9fbc2SHans de Goede cfg.init_data = &init_data; 214a2f9fbc2SHans de Goede cfg.ena_gpiod = int3472->regulator.gpio; 215a2f9fbc2SHans de Goede 2168f3cbcd6SChiYuan Huang int3472->regulator.rdev = regulator_register(int3472->dev, 2178f3cbcd6SChiYuan Huang &int3472->regulator.rdesc, 218a2f9fbc2SHans de Goede &cfg); 219a2f9fbc2SHans de Goede if (IS_ERR(int3472->regulator.rdev)) { 220a2f9fbc2SHans de Goede ret = PTR_ERR(int3472->regulator.rdev); 221a2f9fbc2SHans de Goede goto err_free_gpio; 222a2f9fbc2SHans de Goede } 223a2f9fbc2SHans de Goede 224a2f9fbc2SHans de Goede return 0; 225a2f9fbc2SHans de Goede 226a2f9fbc2SHans de Goede err_free_gpio: 227a2f9fbc2SHans de Goede gpiod_put(int3472->regulator.gpio); 228a2f9fbc2SHans de Goede 229a2f9fbc2SHans de Goede return ret; 230a2f9fbc2SHans de Goede } 231a2f9fbc2SHans de Goede 232a2f9fbc2SHans de Goede void skl_int3472_unregister_regulator(struct int3472_discrete_device *int3472) 233a2f9fbc2SHans de Goede { 234a2f9fbc2SHans de Goede regulator_unregister(int3472->regulator.rdev); 235a2f9fbc2SHans de Goede gpiod_put(int3472->regulator.gpio); 236a2f9fbc2SHans de Goede } 237