static struct matrix_keypad_platform_data *
matrix_keypad_parse_dt(struct device *dev)
{
	struct matrix_keypad_platform_data *pdata;
	struct device_node *np = dev->of_node;
	unsigned int *gpios;
	int i, nrow, ncol;

	if (!np) {
		dev_err(dev, "device lacks DT data\n");
		return ERR_PTR(-ENODEV);
	}

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata) {
		dev_err(dev, "could not allocate memory for platform data\n");
		return ERR_PTR(-ENOMEM);
	}

	pdata->num_row_gpios = nrow = of_gpio_named_count(np, "row-gpios");
	pdata->num_col_gpios = ncol = of_gpio_named_count(np, "col-gpios");
	if (nrow <= 0 || ncol <= 0) {
		dev_err(dev, "number of keypad rows/columns not specified\n");
		return ERR_PTR(-EINVAL);
	}

	if (of_get_property(np, "linux,no-autorepeat", NULL))
		pdata->no_autorepeat = true;
	if (of_get_property(np, "linux,wakeup", NULL))
		pdata->wakeup = true;
	if (of_get_property(np, "gpio-activelow", NULL))
		pdata->active_low = true;

	of_property_read_u32(np, "debounce-delay-ms", &pdata->debounce_ms);
	of_property_read_u32(np, "col-scan-delay-us",
						&pdata->col_scan_delay_us);

	gpios = devm_kzalloc(dev,
			     sizeof(unsigned int) *
				(pdata->num_row_gpios + pdata->num_col_gpios),
			     GFP_KERNEL);
	if (!gpios) {
		dev_err(dev, "could not allocate memory for gpios\n");
		return ERR_PTR(-ENOMEM);
	}

	for (i = 0; i < pdata->num_row_gpios; i++)
		gpios[i] = of_get_named_gpio(np, "row-gpios", i);

	for (i = 0; i < pdata->num_col_gpios; i++)
		gpios[pdata->num_row_gpios + i] =
			of_get_named_gpio(np, "col-gpios", i);

	pdata->row_gpios = gpios;
	pdata->col_gpios = &gpios[pdata->num_row_gpios];

	return pdata;
}
Ejemplo n.º 2
0
static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
{
	struct mmc_pwrseq_simple *spwrseq;
	struct device *dev = &pdev->dev;
	int nr_gpios;

	nr_gpios = of_gpio_named_count(dev->of_node, "reset-gpios");
	if (nr_gpios < 0)
		nr_gpios = 0;

	spwrseq = devm_kzalloc(dev, sizeof(struct mmc_pwrseq_simple) + nr_gpios *
			 sizeof(struct gpio_desc *), GFP_KERNEL);
	if (!spwrseq)
		return -ENOMEM;

	spwrseq->pwrseq.dev = dev;
	spwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops;

	platform_set_drvdata(pdev, spwrseq);

	return mmc_pwrseq_register(&spwrseq->pwrseq);
}
Ejemplo n.º 3
0
static int efm32_spi_probe(struct platform_device *pdev)
{
	struct efm32_spi_ddata *ddata;
	struct resource *res;
	int ret;
	struct spi_master *master;
	struct device_node *np = pdev->dev.of_node;
	int num_cs, i;

	if (!np)
		return -EINVAL;

	num_cs = of_gpio_named_count(np, "cs-gpios");
	if (num_cs < 0)
		return num_cs;

	master = spi_alloc_master(&pdev->dev,
			sizeof(*ddata) + num_cs * sizeof(unsigned));
	if (!master) {
		dev_dbg(&pdev->dev,
				"failed to allocate spi master controller\n");
		return -ENOMEM;
	}
	platform_set_drvdata(pdev, master);

	master->dev.of_node = pdev->dev.of_node;

	master->num_chipselect = num_cs;
	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);

	ddata = spi_master_get_devdata(master);

	ddata->bitbang.master = master;
	ddata->bitbang.chipselect = efm32_spi_chipselect;
	ddata->bitbang.setup_transfer = efm32_spi_setup_transfer;
	ddata->bitbang.txrx_bufs = efm32_spi_txrx_bufs;

	spin_lock_init(&ddata->lock);
	init_completion(&ddata->done);

	ddata->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(ddata->clk)) {
		ret = PTR_ERR(ddata->clk);
		dev_err(&pdev->dev, "failed to get clock: %d\n", ret);
		goto err;
	}

	for (i = 0; i < num_cs; ++i) {
		ret = of_get_named_gpio(np, "cs-gpios", i);
		if (ret < 0) {
			dev_err(&pdev->dev, "failed to get csgpio#%u (%d)\n",
					i, ret);
			goto err;
		}
		ddata->csgpio[i] = ret;
		dev_dbg(&pdev->dev, "csgpio#%u = %u\n", i, ddata->csgpio[i]);
		ret = devm_gpio_request_one(&pdev->dev, ddata->csgpio[i],
				GPIOF_OUT_INIT_LOW, DRIVER_NAME);
		if (ret < 0) {
			dev_err(&pdev->dev,
					"failed to configure csgpio#%u (%d)\n",
					i, ret);
			goto err;
		}
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		ret = -ENODEV;
		dev_err(&pdev->dev, "failed to determine base address\n");
		goto err;
	}

	if (resource_size(res) < 0x60) {
		ret = -EINVAL;
		dev_err(&pdev->dev, "memory resource too small\n");
		goto err;
	}

	ddata->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(ddata->base)) {
		ret = PTR_ERR(ddata->base);
		goto err;
	}

	ret = platform_get_irq(pdev, 0);
	if (ret <= 0) {
		dev_err(&pdev->dev, "failed to get rx irq (%d)\n", ret);
		goto err;
	}

	ddata->rxirq = ret;

	ret = platform_get_irq(pdev, 1);
	if (ret <= 0)
		ret = ddata->rxirq + 1;

	ddata->txirq = ret;

	ret = clk_prepare_enable(ddata->clk);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to enable clock (%d)\n", ret);
		goto err;
	}

	efm32_spi_probe_dt(pdev, master, ddata);

	efm32_spi_write32(ddata, 0, REG_IEN);
	efm32_spi_write32(ddata, REG_ROUTE_TXPEN | REG_ROUTE_RXPEN |
			REG_ROUTE_CLKPEN |
			REG_ROUTE_LOCATION(ddata->pdata.location), REG_ROUTE);

	ret = request_irq(ddata->rxirq, efm32_spi_rxirq,
			0, DRIVER_NAME " rx", ddata);
	if (ret) {
		dev_err(&pdev->dev, "failed to register rxirq (%d)\n", ret);
		goto err_disable_clk;
	}

	ret = request_irq(ddata->txirq, efm32_spi_txirq,
			0, DRIVER_NAME " tx", ddata);
	if (ret) {
		dev_err(&pdev->dev, "failed to register txirq (%d)\n", ret);
		goto err_free_rx_irq;
	}

	ret = spi_bitbang_start(&ddata->bitbang);
	if (ret) {
		dev_err(&pdev->dev, "spi_bitbang_start failed (%d)\n", ret);

		free_irq(ddata->txirq, ddata);
err_free_rx_irq:
		free_irq(ddata->rxirq, ddata);
err_disable_clk:
		clk_disable_unprepare(ddata->clk);
err:
		spi_master_put(master);
	}

	return ret;
}
static int tpiu_parse_of_data(struct platform_device *pdev,
					struct tpiu_drvdata *drvdata)
{
	struct device_node *node = pdev->dev.of_node;
	struct device_node *reg_node = NULL;
	struct device *dev = &pdev->dev;
	const __be32 *prop;
	int i, len, gpio, ret;
	uint32_t *seta_cfgs, *setb_cfgs;
	struct pinctrl *pctrl;

	reg_node = of_parse_phandle(node, "vdd-supply", 0);
	if (reg_node) {
		drvdata->reg = devm_regulator_get(dev, "vdd");
		if (IS_ERR(drvdata->reg))
			return PTR_ERR(drvdata->reg);

		prop = of_get_property(node, "qcom,vdd-voltage-level", &len);
		if (!prop || (len != (2 * sizeof(__be32)))) {
			dev_err(dev, "sdc voltage levels not specified\n");
		} else {
			drvdata->reg_low = be32_to_cpup(&prop[0]);
			drvdata->reg_high = be32_to_cpup(&prop[1]);
		}

		prop = of_get_property(node, "qcom,vdd-current-level", &len);
		if (!prop || (len != (2 * sizeof(__be32)))) {
			dev_err(dev, "sdc current levels not specified\n");
		} else {
			drvdata->reg_lpm = be32_to_cpup(&prop[0]);
			drvdata->reg_hpm = be32_to_cpup(&prop[1]);
		}
		of_node_put(reg_node);
	} else {
		dev_err(dev, "sdc voltage supply not specified or available\n");
	}

	reg_node = of_parse_phandle(node, "vdd-io-supply", 0);
	if (reg_node) {
		drvdata->reg_io = devm_regulator_get(dev, "vdd-io");
		if (IS_ERR(drvdata->reg_io))
			return PTR_ERR(drvdata->reg_io);

		prop = of_get_property(node, "qcom,vdd-io-voltage-level", &len);
		if (!prop || (len != (2 * sizeof(__be32)))) {
			dev_err(dev, "sdc io voltage levels not specified\n");
		} else {
			drvdata->reg_low_io = be32_to_cpup(&prop[0]);
			drvdata->reg_high_io = be32_to_cpup(&prop[1]);
		}

		prop = of_get_property(node, "qcom,vdd-io-current-level", &len);
		if (!prop || (len != (2 * sizeof(__be32)))) {
			dev_err(dev, "sdc io current levels not specified\n");
		} else {
			drvdata->reg_lpm_io = be32_to_cpup(&prop[0]);
			drvdata->reg_hpm_io = be32_to_cpup(&prop[1]);
		}
		of_node_put(reg_node);
	} else {
		dev_err(dev,
			"sdc io voltage supply not specified or available\n");
	}

	drvdata->out_mode = TPIU_OUT_MODE_MICTOR;
	drvdata->set = TPIU_SET_B;

	pctrl = devm_pinctrl_get(dev);
	if (!IS_ERR(pctrl)) {
		drvdata->tpiu_pctrl = devm_kzalloc(dev,
						   sizeof(struct tpiu_pinctrl),
						   GFP_KERNEL);
		if (!drvdata->tpiu_pctrl)
			return -ENOMEM;
		devm_pinctrl_put(pctrl);
		goto out;
	}

	dev_err(dev, "Pinctrl failed, falling back to GPIO lib\n");

	drvdata->seta_gpiocnt = of_gpio_named_count(node, "qcom,seta-gpios");
	if (drvdata->seta_gpiocnt > 0) {
		drvdata->seta_gpios = devm_kzalloc(dev,
				sizeof(*drvdata->seta_gpios) *
				drvdata->seta_gpiocnt, GFP_KERNEL);
		if (!drvdata->seta_gpios)
			return -ENOMEM;

		for (i = 0; i < drvdata->seta_gpiocnt; i++) {
			gpio = of_get_named_gpio(node, "qcom,seta-gpios", i);
			if (!gpio_is_valid(gpio))
				return gpio;

			drvdata->seta_gpios[i] = gpio;
		}

		drvdata->seta_cfgs = devm_kzalloc(dev,
				sizeof(*drvdata->seta_cfgs) *
				drvdata->seta_gpiocnt, GFP_KERNEL);
		if (!drvdata->seta_cfgs)
			return -ENOMEM;

		seta_cfgs = devm_kzalloc(dev, sizeof(*seta_cfgs) *
					 drvdata->seta_gpiocnt, GFP_KERNEL);
		if (!seta_cfgs)
			return -ENOMEM;

		ret = of_property_read_u32_array(node, "qcom,seta-gpios-func",
						 (u32 *)seta_cfgs,
						 drvdata->seta_gpiocnt);
		if (ret)
			return ret;

		for (i = 0; i < drvdata->seta_gpiocnt; i++)
			drvdata->seta_cfgs[i].func = seta_cfgs[i];

		ret = of_property_read_u32_array(node, "qcom,seta-gpios-drv",
						 (u32 *)seta_cfgs,
						 drvdata->seta_gpiocnt);
		if (ret)
			return ret;

		for (i = 0; i < drvdata->seta_gpiocnt; i++)
			drvdata->seta_cfgs[i].drv = seta_cfgs[i];

		ret = of_property_read_u32_array(node, "qcom,seta-gpios-pull",
						 (u32 *)seta_cfgs,
						 drvdata->seta_gpiocnt);
		if (ret)
			return ret;

		for (i = 0; i < drvdata->seta_gpiocnt; i++)
			drvdata->seta_cfgs[i].pull = seta_cfgs[i];

		ret = of_property_read_u32_array(node, "qcom,seta-gpios-dir",
						 (u32 *)seta_cfgs,
						 drvdata->seta_gpiocnt);
		if (ret)
			return ret;

		for (i = 0; i < drvdata->seta_gpiocnt; i++)
			drvdata->seta_cfgs[i].dir = seta_cfgs[i];

		devm_kfree(dev, seta_cfgs);
	} else {
		dev_err(dev, "seta gpios not specified\n");
	}

	drvdata->setb_gpiocnt = of_gpio_named_count(node, "qcom,setb-gpios");
	if (drvdata->setb_gpiocnt > 0) {
		drvdata->setb_gpios = devm_kzalloc(dev,
				sizeof(*drvdata->setb_gpios) *
				drvdata->setb_gpiocnt, GFP_KERNEL);
		if (!drvdata->setb_gpios)
			return -ENOMEM;

		for (i = 0; i < drvdata->setb_gpiocnt; i++) {
			gpio = of_get_named_gpio(node, "qcom,setb-gpios", i);
			if (!gpio_is_valid(gpio))
				return gpio;

			drvdata->setb_gpios[i] = gpio;
		}

		drvdata->setb_cfgs = devm_kzalloc(dev,
				sizeof(*drvdata->setb_cfgs) *
				drvdata->setb_gpiocnt, GFP_KERNEL);
		if (!drvdata->setb_cfgs)
			return -ENOMEM;

		setb_cfgs = devm_kzalloc(dev, sizeof(*setb_cfgs) *
					 drvdata->setb_gpiocnt, GFP_KERNEL);
		if (!setb_cfgs)
			return -ENOMEM;

		ret = of_property_read_u32_array(node, "qcom,setb-gpios-func",
						 (u32 *)setb_cfgs,
						 drvdata->setb_gpiocnt);
		if (ret)
			return ret;

		for (i = 0; i < drvdata->setb_gpiocnt; i++)
			drvdata->setb_cfgs[i].func = setb_cfgs[i];

		ret = of_property_read_u32_array(node, "qcom,setb-gpios-drv",
						 (u32 *)setb_cfgs,
						 drvdata->setb_gpiocnt);
		if (ret)
			return ret;

		for (i = 0; i < drvdata->setb_gpiocnt; i++)
			drvdata->setb_cfgs[i].drv = setb_cfgs[i];

		ret = of_property_read_u32_array(node, "qcom,setb-gpios-pull",
						 (u32 *)setb_cfgs,
						 drvdata->setb_gpiocnt);
		if (ret)
			return ret;

		for (i = 0; i < drvdata->setb_gpiocnt; i++)
			drvdata->setb_cfgs[i].pull = setb_cfgs[i];

		ret = of_property_read_u32_array(node, "qcom,setb-gpios-dir",
						 (u32 *)setb_cfgs,
						 drvdata->setb_gpiocnt);
		if (ret)
			return ret;

		for (i = 0; i < drvdata->setb_gpiocnt; i++)
			drvdata->setb_cfgs[i].dir = setb_cfgs[i];

		devm_kfree(dev, setb_cfgs);
	} else {
		dev_err(dev, "setb gpios not specified\n");
	}
out:
	drvdata->nidnt = of_property_read_bool(pdev->dev.of_node,
					       "qcom,nidnt");
	return 0;
}