brintos

brintos / linux-shallow public Read only

0
0
Text · 8.4 KiB · 16e36ac Raw
315 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Author: Dan Scally <djrscally@gmail.com> */3 4#include <linux/acpi.h>5#include <linux/clkdev.h>6#include <linux/clk-provider.h>7#include <linux/device.h>8#include <linux/dmi.h>9#include <linux/gpio/consumer.h>10#include <linux/regulator/driver.h>11#include <linux/slab.h>12 13#include "common.h"14 15/*16 * 82c0d13a-78c5-4244-9bb1-eb8b539a8d1117 * This _DSM GUID allows controlling the sensor clk when it is not controlled18 * through a GPIO.19 */20static const guid_t img_clk_guid =21	GUID_INIT(0x82c0d13a, 0x78c5, 0x4244,22		  0x9b, 0xb1, 0xeb, 0x8b, 0x53, 0x9a, 0x8d, 0x11);23 24static void skl_int3472_enable_clk(struct int3472_clock *clk, int enable)25{26	struct int3472_discrete_device *int3472 = to_int3472_device(clk);27	union acpi_object args[3];28	union acpi_object argv4;29 30	if (clk->ena_gpio) {31		gpiod_set_value_cansleep(clk->ena_gpio, enable);32		return;33	}34 35	args[0].integer.type = ACPI_TYPE_INTEGER;36	args[0].integer.value = clk->imgclk_index;37	args[1].integer.type = ACPI_TYPE_INTEGER;38	args[1].integer.value = enable;39	args[2].integer.type = ACPI_TYPE_INTEGER;40	args[2].integer.value = 1;41 42	argv4.type = ACPI_TYPE_PACKAGE;43	argv4.package.count = 3;44	argv4.package.elements = args;45 46	acpi_evaluate_dsm(acpi_device_handle(int3472->adev), &img_clk_guid,47			  0, 1, &argv4);48}49 50/*51 * The regulators have to have .ops to be valid, but the only ops we actually52 * support are .enable and .disable which are handled via .ena_gpiod. Pass an53 * empty struct to clear the check without lying about capabilities.54 */55static const struct regulator_ops int3472_gpio_regulator_ops;56 57static int skl_int3472_clk_prepare(struct clk_hw *hw)58{59	skl_int3472_enable_clk(to_int3472_clk(hw), 1);60	return 0;61}62 63static void skl_int3472_clk_unprepare(struct clk_hw *hw)64{65	skl_int3472_enable_clk(to_int3472_clk(hw), 0);66}67 68static int skl_int3472_clk_enable(struct clk_hw *hw)69{70	/*71	 * We're just turning a GPIO on to enable the clock, which operation72	 * has the potential to sleep. Given .enable() cannot sleep, but73	 * .prepare() can, we toggle the GPIO in .prepare() instead. Thus,74	 * nothing to do here.75	 */76	return 0;77}78 79static void skl_int3472_clk_disable(struct clk_hw *hw)80{81	/* Likewise, nothing to do here... */82}83 84static unsigned int skl_int3472_get_clk_frequency(struct int3472_discrete_device *int3472)85{86	union acpi_object *obj;87	unsigned int freq;88 89	obj = skl_int3472_get_acpi_buffer(int3472->sensor, "SSDB");90	if (IS_ERR(obj))91		return 0; /* report rate as 0 on error */92 93	if (obj->buffer.length < CIO2_SENSOR_SSDB_MCLKSPEED_OFFSET + sizeof(u32)) {94		dev_err(int3472->dev, "The buffer is too small\n");95		kfree(obj);96		return 0;97	}98 99	freq = *(u32 *)(obj->buffer.pointer + CIO2_SENSOR_SSDB_MCLKSPEED_OFFSET);100 101	kfree(obj);102	return freq;103}104 105static unsigned long skl_int3472_clk_recalc_rate(struct clk_hw *hw,106						 unsigned long parent_rate)107{108	struct int3472_clock *clk = to_int3472_clk(hw);109 110	return clk->frequency;111}112 113static const struct clk_ops skl_int3472_clock_ops = {114	.prepare = skl_int3472_clk_prepare,115	.unprepare = skl_int3472_clk_unprepare,116	.enable = skl_int3472_clk_enable,117	.disable = skl_int3472_clk_disable,118	.recalc_rate = skl_int3472_clk_recalc_rate,119};120 121int skl_int3472_register_dsm_clock(struct int3472_discrete_device *int3472)122{123	struct acpi_device *adev = int3472->adev;124	struct clk_init_data init = {125		.ops = &skl_int3472_clock_ops,126		.flags = CLK_GET_RATE_NOCACHE,127	};128	int ret;129 130	if (int3472->clock.cl)131		return 0; /* A GPIO controlled clk has already been registered */132 133	if (!acpi_check_dsm(adev->handle, &img_clk_guid, 0, BIT(1)))134		return 0; /* DSM clock control is not available */135 136	init.name = kasprintf(GFP_KERNEL, "%s-clk", acpi_dev_name(adev));137	if (!init.name)138		return -ENOMEM;139 140	int3472->clock.frequency = skl_int3472_get_clk_frequency(int3472);141	int3472->clock.clk_hw.init = &init;142	int3472->clock.clk = clk_register(&adev->dev, &int3472->clock.clk_hw);143	if (IS_ERR(int3472->clock.clk)) {144		ret = PTR_ERR(int3472->clock.clk);145		goto out_free_init_name;146	}147 148	int3472->clock.cl = clkdev_create(int3472->clock.clk, NULL, int3472->sensor_name);149	if (!int3472->clock.cl) {150		ret = -ENOMEM;151		goto err_unregister_clk;152	}153 154	kfree(init.name);155	return 0;156 157err_unregister_clk:158	clk_unregister(int3472->clock.clk);159out_free_init_name:160	kfree(init.name);161	return ret;162}163 164int skl_int3472_register_gpio_clock(struct int3472_discrete_device *int3472,165				    struct gpio_desc *gpio)166{167	struct clk_init_data init = {168		.ops = &skl_int3472_clock_ops,169		.flags = CLK_GET_RATE_NOCACHE,170	};171	int ret;172 173	if (int3472->clock.cl)174		return -EBUSY;175 176	int3472->clock.ena_gpio = gpio;177 178	init.name = kasprintf(GFP_KERNEL, "%s-clk",179			      acpi_dev_name(int3472->adev));180	if (!init.name)181		return -ENOMEM;182 183	int3472->clock.frequency = skl_int3472_get_clk_frequency(int3472);184 185	int3472->clock.clk_hw.init = &init;186	int3472->clock.clk = clk_register(&int3472->adev->dev,187					  &int3472->clock.clk_hw);188	if (IS_ERR(int3472->clock.clk)) {189		ret = PTR_ERR(int3472->clock.clk);190		goto out_free_init_name;191	}192 193	int3472->clock.cl = clkdev_create(int3472->clock.clk, NULL,194					  int3472->sensor_name);195	if (!int3472->clock.cl) {196		ret = -ENOMEM;197		goto err_unregister_clk;198	}199 200	kfree(init.name);201	return 0;202 203err_unregister_clk:204	clk_unregister(int3472->clock.clk);205out_free_init_name:206	kfree(init.name);207 208	return ret;209}210 211void skl_int3472_unregister_clock(struct int3472_discrete_device *int3472)212{213	if (!int3472->clock.cl)214		return;215 216	clkdev_drop(int3472->clock.cl);217	clk_unregister(int3472->clock.clk);218}219 220/*221 * The INT3472 device is going to be the only supplier of a regulator for222 * the sensor device. But unlike the clk framework the regulator framework223 * does not allow matching by consumer-device-name only.224 *225 * Ideally all sensor drivers would use "avdd" as supply-id. But for drivers226 * where this cannot be changed because another supply-id is already used in227 * e.g. DeviceTree files an alias for the other supply-id can be added here.228 *229 * Do not forget to update GPIO_REGULATOR_SUPPLY_MAP_COUNT when changing this.230 */231static const char * const skl_int3472_regulator_map_supplies[] = {232	"avdd",233	"AVDD",234};235 236static_assert(ARRAY_SIZE(skl_int3472_regulator_map_supplies) ==237	      GPIO_REGULATOR_SUPPLY_MAP_COUNT);238 239/*240 * On some models there is a single GPIO regulator which is shared between241 * sensors and only listed in the ACPI resources of one sensor.242 * This DMI table contains the name of the second sensor. This is used to add243 * entries for the second sensor to the supply_map.244 */245static const struct dmi_system_id skl_int3472_regulator_second_sensor[] = {246	{247		/* Lenovo Miix 510-12IKB */248		.matches = {249			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),250			DMI_MATCH(DMI_PRODUCT_VERSION, "MIIX 510-12IKB"),251		},252		.driver_data = "i2c-OVTI2680:00",253	},254	{ }255};256 257int skl_int3472_register_regulator(struct int3472_discrete_device *int3472,258				   struct gpio_desc *gpio)259{260	struct regulator_init_data init_data = { };261	struct regulator_config cfg = { };262	const char *second_sensor = NULL;263	const struct dmi_system_id *id;264	int i, j;265 266	id = dmi_first_match(skl_int3472_regulator_second_sensor);267	if (id)268		second_sensor = id->driver_data;269 270	for (i = 0, j = 0; i < ARRAY_SIZE(skl_int3472_regulator_map_supplies); i++) {271		int3472->regulator.supply_map[j].supply = skl_int3472_regulator_map_supplies[i];272		int3472->regulator.supply_map[j].dev_name = int3472->sensor_name;273		j++;274 275		if (second_sensor) {276			int3472->regulator.supply_map[j].supply =277				skl_int3472_regulator_map_supplies[i];278			int3472->regulator.supply_map[j].dev_name = second_sensor;279			j++;280		}281	}282 283	init_data.constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;284	init_data.consumer_supplies = int3472->regulator.supply_map;285	init_data.num_consumer_supplies = j;286 287	snprintf(int3472->regulator.regulator_name,288		 sizeof(int3472->regulator.regulator_name), "%s-regulator",289		 acpi_dev_name(int3472->adev));290	snprintf(int3472->regulator.supply_name,291		 GPIO_REGULATOR_SUPPLY_NAME_LENGTH, "supply-0");292 293	int3472->regulator.rdesc = INT3472_REGULATOR(294						int3472->regulator.regulator_name,295						int3472->regulator.supply_name,296						&int3472_gpio_regulator_ops);297 298	int3472->regulator.gpio = gpio;299 300	cfg.dev = &int3472->adev->dev;301	cfg.init_data = &init_data;302	cfg.ena_gpiod = int3472->regulator.gpio;303 304	int3472->regulator.rdev = regulator_register(int3472->dev,305						     &int3472->regulator.rdesc,306						     &cfg);307 308	return PTR_ERR_OR_ZERO(int3472->regulator.rdev);309}310 311void skl_int3472_unregister_regulator(struct int3472_discrete_device *int3472)312{313	regulator_unregister(int3472->regulator.rdev);314}315