static int tpd_init_pins(struct platform_device *pdev)
{
	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
	struct device_node *node;

	ddata->pins = devm_pinctrl_get(&pdev->dev);
	if (IS_ERR(ddata->pins))
		return PTR_ERR(ddata->pins);

	ddata->pin_state_i2c = pinctrl_lookup_state(ddata->pins, "i2c");
	if (IS_ERR(ddata->pin_state_i2c))
		return PTR_ERR(ddata->pin_state_i2c);

	ddata->pin_state_ddc = pinctrl_lookup_state(ddata->pins, "ddc");
	if (IS_ERR(ddata->pin_state_ddc))
		return PTR_ERR(ddata->pin_state_ddc);

	node = of_parse_phandle(pdev->dev.of_node, "ddc-i2c-bus", 0);
	if (!node)
		return -ENODEV;

	ddata->ddc_i2c_adapter = of_find_i2c_adapter_by_node(node);
	if (!ddata->ddc_i2c_adapter)
		return -ENODEV;

	return 0;
}
예제 #2
0
static int i2c_mux_reg_probe_dt(struct regmux *mux,
				struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device_node *adapter_np, *child;
	struct i2c_adapter *adapter;
	struct resource res;
	unsigned *values;
	int i = 0;

	if (!np)
		return -ENODEV;

	adapter_np = of_parse_phandle(np, "i2c-parent", 0);
	if (!adapter_np) {
		dev_err(&pdev->dev, "Cannot parse i2c-parent\n");
		return -ENODEV;
	}
	adapter = of_find_i2c_adapter_by_node(adapter_np);
	of_node_put(adapter_np);
	if (!adapter)
		return -EPROBE_DEFER;

	mux->data.parent = i2c_adapter_id(adapter);
	put_device(&adapter->dev);

	mux->data.n_values = of_get_child_count(np);
	if (of_find_property(np, "little-endian", NULL)) {
		mux->data.little_endian = true;
	} else if (of_find_property(np, "big-endian", NULL)) {
		mux->data.little_endian = false;
	} else {
#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : \
	defined(__LITTLE_ENDIAN)
		mux->data.little_endian = true;
#elif defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : \
	defined(__BIG_ENDIAN)
		mux->data.little_endian = false;
#else
#error Endianness not defined?
#endif
	}
	if (of_find_property(np, "write-only", NULL))
		mux->data.write_only = true;
	else
		mux->data.write_only = false;

	values = devm_kzalloc(&pdev->dev,
			      sizeof(*mux->data.values) * mux->data.n_values,
			      GFP_KERNEL);
	if (!values) {
		dev_err(&pdev->dev, "Cannot allocate values array");
		return -ENOMEM;
	}

	for_each_child_of_node(np, child) {
		of_property_read_u32(child, "reg", values + i);
		i++;
	}
예제 #3
0
/* must call i2c_put_adapter() when done with returned i2c_adapter device */
struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node)
{
	struct i2c_adapter *adapter;

	adapter = of_find_i2c_adapter_by_node(node);
	if (!adapter)
		return NULL;

	if (!try_module_get(adapter->owner)) {
		put_device(&adapter->dev);
		adapter = NULL;
	}

	return adapter;
}
예제 #4
0
static int of_i2c_notify(struct notifier_block *nb, unsigned long action,
			 void *arg)
{
	struct of_reconfig_data *rd = arg;
	struct i2c_adapter *adap;
	struct i2c_client *client;

	switch (of_reconfig_get_state_change(action, rd)) {
	case OF_RECONFIG_CHANGE_ADD:
		adap = of_find_i2c_adapter_by_node(rd->dn->parent);
		if (adap == NULL)
			return NOTIFY_OK;	/* not for us */

		if (of_node_test_and_set_flag(rd->dn, OF_POPULATED)) {
			put_device(&adap->dev);
			return NOTIFY_OK;
		}

		client = of_i2c_register_device(adap, rd->dn);
		put_device(&adap->dev);

		if (IS_ERR(client)) {
			dev_err(&adap->dev, "failed to create client for '%pOF'\n",
				 rd->dn);
			of_node_clear_flag(rd->dn, OF_POPULATED);
			return notifier_from_errno(PTR_ERR(client));
		}
		break;
	case OF_RECONFIG_CHANGE_REMOVE:
		/* already depopulated? */
		if (!of_node_check_flag(rd->dn, OF_POPULATED))
			return NOTIFY_OK;

		/* find our device by node */
		client = of_find_i2c_device_by_node(rd->dn);
		if (client == NULL)
			return NOTIFY_OK;	/* no? not meant for us */

		/* unregister takes one ref away */
		i2c_unregister_device(client);

		/* and put the reference of the find */
		put_device(&client->dev);
		break;
	}

	return NOTIFY_OK;
}
예제 #5
0
static int simple_panel_get_modes(struct simple_panel *panel, struct display_timings *timings)
{
	int ret = -ENOENT;

	if (panel->ddc_node && IS_ENABLED(CONFIG_DRIVER_VIDEO_EDID) &&
	    IS_ENABLED(CONFIG_I2C)) {
		struct i2c_adapter *i2c;

                i2c = of_find_i2c_adapter_by_node(panel->ddc_node);
		if (!i2c)
			return -ENODEV;
		timings->edid = edid_read_i2c(i2c);
		if (!timings->edid)
			return -EINVAL;

		ret = edid_to_display_timings(timings, timings->edid);
	}

	return ret;
}
static int i2c_mux_gpio_probe_dt(struct gpiomux *mux,
					struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device_node *adapter_np, *child;
	struct i2c_adapter *adapter;
	unsigned *values, *gpios;
	int i = 0, ret;

	if (!np)
		return -ENODEV;

	adapter_np = of_parse_phandle(np, "i2c-parent", 0);
	if (!adapter_np) {
		dev_err(&pdev->dev, "Cannot parse i2c-parent\n");
		return -ENODEV;
	}
	adapter = of_find_i2c_adapter_by_node(adapter_np);
	if (!adapter) {
		dev_err(&pdev->dev, "Cannot find parent bus\n");
		return -EPROBE_DEFER;
	}
	mux->data.parent = i2c_adapter_id(adapter);
	put_device(&adapter->dev);

	mux->data.n_values = of_get_child_count(np);

	values = devm_kzalloc(&pdev->dev,
			      sizeof(*mux->data.values) * mux->data.n_values,
			      GFP_KERNEL);
	if (!values) {
		dev_err(&pdev->dev, "Cannot allocate values array");
		return -ENOMEM;
	}

	for_each_child_of_node(np, child) {
		of_property_read_u32(child, "reg", values + i);
		i++;
	}
예제 #7
0
파일: output.c 프로젝트: 383530895/linux
int tegra_output_probe(struct tegra_output *output)
{
	struct device_node *ddc, *panel;
	enum of_gpio_flags flags;
	int err, size;

	if (!output->of_node)
		output->of_node = output->dev->of_node;

	panel = of_parse_phandle(output->of_node, "nvidia,panel", 0);
	if (panel) {
		output->panel = of_drm_find_panel(panel);
		if (!output->panel)
			return -EPROBE_DEFER;

		of_node_put(panel);
	}

	output->edid = of_get_property(output->of_node, "nvidia,edid", &size);

	ddc = of_parse_phandle(output->of_node, "nvidia,ddc-i2c-bus", 0);
	if (ddc) {
		output->ddc = of_find_i2c_adapter_by_node(ddc);
		if (!output->ddc) {
			err = -EPROBE_DEFER;
			of_node_put(ddc);
			return err;
		}

		of_node_put(ddc);
	}

	output->hpd_gpio = of_get_named_gpio_flags(output->of_node,
						   "nvidia,hpd-gpio", 0,
						   &flags);
	if (gpio_is_valid(output->hpd_gpio)) {
		unsigned long flags;

		err = gpio_request_one(output->hpd_gpio, GPIOF_DIR_IN,
				       "HDMI hotplug detect");
		if (err < 0) {
			dev_err(output->dev, "gpio_request_one(): %d\n", err);
			return err;
		}

		err = gpio_to_irq(output->hpd_gpio);
		if (err < 0) {
			dev_err(output->dev, "gpio_to_irq(): %d\n", err);
			gpio_free(output->hpd_gpio);
			return err;
		}

		output->hpd_irq = err;

		flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
			IRQF_ONESHOT;

		err = request_threaded_irq(output->hpd_irq, NULL, hpd_irq,
					   flags, "hpd", output);
		if (err < 0) {
			dev_err(output->dev, "failed to request IRQ#%u: %d\n",
				output->hpd_irq, err);
			gpio_free(output->hpd_gpio);
			return err;
		}

		output->connector.polled = DRM_CONNECTOR_POLL_HPD;

		/*
		 * Disable the interrupt until the connector has been
		 * initialized to avoid a race in the hotplug interrupt
		 * handler.
		 */
		disable_irq(output->hpd_irq);
	}

	return 0;
}
예제 #8
0
static int i2c_arbitrator_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct device_node *parent_np;
	struct i2c_arbitrator_data *arb;
	enum of_gpio_flags gpio_flags;
	unsigned long out_init;
	int ret;

	/* We only support probing from device tree; no platform_data */
	if (!np) {
		dev_err(dev, "Cannot find device tree node\n");
		return -ENODEV;
	}
	if (dev->platform_data) {
		dev_err(dev, "Platform data is not supported\n");
		return -EINVAL;
	}

	arb = devm_kzalloc(dev, sizeof(*arb), GFP_KERNEL);
	if (!arb) {
		dev_err(dev, "Cannot allocate i2c_arbitrator_data\n");
		return -ENOMEM;
	}
	platform_set_drvdata(pdev, arb);

	/* Request GPIOs */
	ret = of_get_named_gpio_flags(np, "our-claim-gpio", 0, &gpio_flags);
	if (!gpio_is_valid(ret)) {
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "Error getting our-claim-gpio\n");
		return ret;
	}
	arb->our_gpio = ret;
	arb->our_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW);
	out_init = (gpio_flags & OF_GPIO_ACTIVE_LOW) ?
		GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
	ret = devm_gpio_request_one(dev, arb->our_gpio, out_init,
				    "our-claim-gpio");
	if (ret) {
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "Error requesting our-claim-gpio\n");
		return ret;
	}

	ret = of_get_named_gpio_flags(np, "their-claim-gpios", 0, &gpio_flags);
	if (!gpio_is_valid(ret)) {
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "Error getting their-claim-gpio\n");
		return ret;
	}
	arb->their_gpio = ret;
	arb->their_gpio_release = !!(gpio_flags & OF_GPIO_ACTIVE_LOW);
	ret = devm_gpio_request_one(dev, arb->their_gpio, GPIOF_IN,
				    "their-claim-gpio");
	if (ret) {
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "Error requesting their-claim-gpio\n");
		return ret;
	}

	/* At the moment we only support a single two master (us + 1 other) */
	if (gpio_is_valid(of_get_named_gpio(np, "their-claim-gpios", 1))) {
		dev_err(dev, "Only one other master is supported\n");
		return -EINVAL;
	}

	/* Arbitration parameters */
	if (of_property_read_u32(np, "slew-delay-us", &arb->slew_delay_us))
		arb->slew_delay_us = 10;
	if (of_property_read_u32(np, "wait-retry-us", &arb->wait_retry_us))
		arb->wait_retry_us = 3000;
	if (of_property_read_u32(np, "wait-free-us", &arb->wait_free_us))
		arb->wait_free_us = 50000;

	/* Find our parent */
	parent_np = of_parse_phandle(np, "i2c-parent", 0);
	if (!parent_np) {
		dev_err(dev, "Cannot parse i2c-parent\n");
		return -EINVAL;
	}
	arb->parent = of_find_i2c_adapter_by_node(parent_np);
	if (!arb->parent) {
		dev_err(dev, "Cannot find parent bus\n");
		return -EINVAL;
	}

	/* Actually add the mux adapter */
	arb->child = i2c_add_mux_adapter(arb->parent, dev, arb, 0, 0, 0,
					 i2c_arbitrator_select,
					 i2c_arbitrator_deselect);
	if (!arb->child) {
		dev_err(dev, "Failed to add adapter\n");
		ret = -ENODEV;
		i2c_put_adapter(arb->parent);
	}

	return ret;
}
예제 #9
0
static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
{
	struct platform_device *pdev = to_platform_device(dev);
	const struct of_device_id *of_id =
				of_match_device(imx_hdmi_dt_ids, dev);
	struct drm_device *drm = data;
	struct device_node *np = dev->of_node;
	struct device_node *ddc_node;
	struct imx_hdmi *hdmi;
	struct resource *iores;
	int ret, irq;

	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
	if (!hdmi)
		return -ENOMEM;

	hdmi->dev = dev;
	hdmi->sample_rate = 48000;
	hdmi->ratio = 100;

	if (of_id) {
		const struct platform_device_id *device_id = of_id->data;
		hdmi->dev_type = device_id->driver_data;
	}

	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
	if (ddc_node) {
		hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
		if (!hdmi->ddc)
			dev_dbg(hdmi->dev, "failed to read ddc node\n");

		of_node_put(ddc_node);
	} else {
		dev_dbg(hdmi->dev, "no ddc property found\n");
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return -EINVAL;

	ret = devm_request_threaded_irq(dev, irq, imx_hdmi_hardirq,
					imx_hdmi_irq, IRQF_SHARED,
					dev_name(dev), hdmi);
	if (ret)
		return ret;

	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	hdmi->regs = devm_ioremap_resource(dev, iores);
	if (IS_ERR(hdmi->regs))
		return PTR_ERR(hdmi->regs);

	hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
	if (IS_ERR(hdmi->regmap))
		return PTR_ERR(hdmi->regmap);

	hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
	if (IS_ERR(hdmi->isfr_clk)) {
		ret = PTR_ERR(hdmi->isfr_clk);
		dev_err(hdmi->dev,
			"Unable to get HDMI isfr clk: %d\n", ret);
		return ret;
	}

	ret = clk_prepare_enable(hdmi->isfr_clk);
	if (ret) {
		dev_err(hdmi->dev,
			"Cannot enable HDMI isfr clock: %d\n", ret);
		return ret;
	}

	hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
	if (IS_ERR(hdmi->iahb_clk)) {
		ret = PTR_ERR(hdmi->iahb_clk);
		dev_err(hdmi->dev,
			"Unable to get HDMI iahb clk: %d\n", ret);
		goto err_isfr;
	}

	ret = clk_prepare_enable(hdmi->iahb_clk);
	if (ret) {
		dev_err(hdmi->dev,
			"Cannot enable HDMI iahb clock: %d\n", ret);
		goto err_isfr;
	}

	/* Product and revision IDs */
	dev_info(dev,
		"Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
		hdmi_readb(hdmi, HDMI_DESIGN_ID),
		hdmi_readb(hdmi, HDMI_REVISION_ID),
		hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
		hdmi_readb(hdmi, HDMI_PRODUCT_ID1));

	initialize_hdmi_ih_mutes(hdmi);

	/*
	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
	 * N and cts values before enabling phy
	 */
	hdmi_init_clk_regenerator(hdmi);

	/*
	 * Configure registers related to HDMI interrupt
	 * generation before registering IRQ.
	 */
	hdmi_writeb(hdmi, HDMI_PHY_HPD, HDMI_PHY_POL0);

	/* Clear Hotplug interrupts */
	hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);

	ret = imx_hdmi_fb_registered(hdmi);
	if (ret)
		goto err_iahb;

	ret = imx_hdmi_register(drm, hdmi);
	if (ret)
		goto err_iahb;

	/* Unmute interrupts */
	hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);

	dev_set_drvdata(dev, hdmi);

	return 0;

err_iahb:
	clk_disable_unprepare(hdmi->iahb_clk);
err_isfr:
	clk_disable_unprepare(hdmi->isfr_clk);

	return ret;
}
예제 #10
0
int dw_hdmi_bind(struct device *dev, struct device *master,
		 void *data, struct drm_encoder *encoder,
		 struct resource *iores, int irq,
		 const struct dw_hdmi_plat_data *plat_data)
{
	struct drm_device *drm = data;
	struct device_node *np = dev->of_node;
	struct device_node *ddc_node;
	struct dw_hdmi *hdmi;
	int ret;
	u32 val = 1;

	hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
	if (!hdmi)
		return -ENOMEM;

	hdmi->plat_data = plat_data;
	hdmi->dev = dev;
	hdmi->dev_type = plat_data->dev_type;
	hdmi->sample_rate = 48000;
	hdmi->ratio = 100;
	hdmi->encoder = encoder;

	mutex_init(&hdmi->audio_mutex);

	of_property_read_u32(np, "reg-io-width", &val);

	switch (val) {
	case 4:
		hdmi->write = dw_hdmi_writel;
		hdmi->read = dw_hdmi_readl;
		break;
	case 1:
		hdmi->write = dw_hdmi_writeb;
		hdmi->read = dw_hdmi_readb;
		break;
	default:
		dev_err(dev, "reg-io-width must be 1 or 4\n");
		return -EINVAL;
	}

	ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0);
	if (ddc_node) {
		hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
		of_node_put(ddc_node);
		if (!hdmi->ddc) {
			dev_dbg(hdmi->dev, "failed to read ddc node\n");
			return -EPROBE_DEFER;
		}

	} else {
		dev_dbg(hdmi->dev, "no ddc property found\n");
	}

	hdmi->regs = devm_ioremap_resource(dev, iores);
	if (IS_ERR(hdmi->regs))
		return PTR_ERR(hdmi->regs);

	hdmi->isfr_clk = devm_clk_get(hdmi->dev, "isfr");
	if (IS_ERR(hdmi->isfr_clk)) {
		ret = PTR_ERR(hdmi->isfr_clk);
		dev_err(hdmi->dev, "Unable to get HDMI isfr clk: %d\n", ret);
		return ret;
	}

	ret = clk_prepare_enable(hdmi->isfr_clk);
	if (ret) {
		dev_err(hdmi->dev, "Cannot enable HDMI isfr clock: %d\n", ret);
		return ret;
	}

	hdmi->iahb_clk = devm_clk_get(hdmi->dev, "iahb");
	if (IS_ERR(hdmi->iahb_clk)) {
		ret = PTR_ERR(hdmi->iahb_clk);
		dev_err(hdmi->dev, "Unable to get HDMI iahb clk: %d\n", ret);
		goto err_isfr;
	}

	ret = clk_prepare_enable(hdmi->iahb_clk);
	if (ret) {
		dev_err(hdmi->dev, "Cannot enable HDMI iahb clock: %d\n", ret);
		goto err_isfr;
	}

	/* Product and revision IDs */
	dev_info(dev,
		 "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
		 hdmi_readb(hdmi, HDMI_DESIGN_ID),
		 hdmi_readb(hdmi, HDMI_REVISION_ID),
		 hdmi_readb(hdmi, HDMI_PRODUCT_ID0),
		 hdmi_readb(hdmi, HDMI_PRODUCT_ID1));

	initialize_hdmi_ih_mutes(hdmi);

	ret = devm_request_threaded_irq(dev, irq, dw_hdmi_hardirq,
					dw_hdmi_irq, IRQF_SHARED,
					dev_name(dev), hdmi);
	if (ret)
		goto err_iahb;

	/*
	 * To prevent overflows in HDMI_IH_FC_STAT2, set the clk regenerator
	 * N and cts values before enabling phy
	 */
	hdmi_init_clk_regenerator(hdmi);

	/*
	 * Configure registers related to HDMI interrupt
	 * generation before registering IRQ.
	 */
	hdmi_writeb(hdmi, HDMI_PHY_HPD, HDMI_PHY_POL0);

	/* Clear Hotplug interrupts */
	hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0);

	ret = dw_hdmi_fb_registered(hdmi);
	if (ret)
		goto err_iahb;

	ret = dw_hdmi_register(drm, hdmi);
	if (ret)
		goto err_iahb;

	/* Unmute interrupts */
	hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0);

	dev_set_drvdata(dev, hdmi);

	return 0;

err_iahb:
	clk_disable_unprepare(hdmi->iahb_clk);
err_isfr:
	clk_disable_unprepare(hdmi->isfr_clk);

	return ret;
}