static int mmi_factory_probe(struct platform_device *pdev)
{
	struct mmi_factory_info *info;
	int ret;
	int i;

	if (!mmi_factory_cable_present()) {
		dev_dbg(&pdev->dev, "factory cable not present\n");
		return -ENODEV;
	}

	info = mmi_parse_of(pdev);
	if (!info) {
		dev_err(&pdev->dev, "failed to parse node\n");
		return -ENODEV;
	}

	ret = gpio_request_array(info->list, info->num_gpios);
	if (ret) {
		dev_err(&pdev->dev, "failed to request GPIOs\n");
		return ret;
	}

	for (i = 0; i < info->num_gpios; i++) {
		ret = gpio_export(info->list[i].gpio, 1);
		if (ret) {
			dev_err(&pdev->dev, "Failed to export GPIO %s: %d\n",
				info->list[i].label, info->list[i].gpio);
			goto fail;
		}

		ret = gpio_export_link(&pdev->dev, info->list[i].label,
					info->list[i].gpio);
		if (ret) {
			dev_err(&pdev->dev, "Failed to link GPIO %s: %d\n",
				info->list[i].label, info->list[i].gpio);
			goto fail;
		}
	}

	platform_set_drvdata(pdev, info);

	return 0;

fail:
	gpio_free_array(info->list, info->num_gpios);
	return ret;
}
Esempio n. 2
0
static int mmi_factory_probe(struct platform_device *pdev)
{
	const struct of_device_id *match;
	struct mmi_factory_info *info;
	int ret;
	int i;

	match = of_match_device(mmi_factory_of_tbl, &pdev->dev);
	if (!match) {
		dev_err(&pdev->dev, "No Match found\n");
		return -ENODEV;
	}

	if (match && match->compatible)
		dev_info(&pdev->dev, "Using %s\n", match->compatible);

	info = mmi_parse_of(pdev);
	if (!info) {
		dev_err(&pdev->dev, "failed to parse node\n");
		return -ENODEV;
	}

	ret = gpio_request_array(info->list, info->num_gpios);
	if (ret) {
		dev_err(&pdev->dev, "failed to request GPIOs\n");
		return ret;
	}

	for (i = 0; i < info->num_gpios; i++) {
		ret = gpio_export(info->list[i].gpio, 1);
		if (ret) {
			dev_err(&pdev->dev, "Failed to export GPIO %s: %d\n",
				info->list[i].label, info->list[i].gpio);
			goto fail;
		}

		ret = gpio_export_link(&pdev->dev, info->list[i].label,
					info->list[i].gpio);
		if (ret) {
			dev_err(&pdev->dev, "Failed to link GPIO %s: %d\n",
				info->list[i].label, info->list[i].gpio);
			goto fail;
		}
	}

	if (!mmi_factory_cable_present()) {
		dev_dbg(&pdev->dev, "factory cable not present\n");
	} else {
		pr_info("Factory Cable Attached at Power up!\n");
		info->factory_cable = 1;
	}

	if (match && match->data) {
		info->dev = *(enum mmi_factory_device_list *)(match->data);
	} else {
		dev_err(&pdev->dev, "failed to find device match\n");
		goto fail;
	}

	if ((info->dev == KUNGPOW) && (info->num_gpios == KP_NUM_GPIOS)) {
		/* Disable Kill if not powered up by a factory cable */
		if (!info->factory_cable)
			gpio_direction_output(info->list[KP_KILL_INDEX].gpio,
						1);
		else {
			ret = device_create_file(&pdev->dev,
						 &dev_attr_usr_rst_sw_dis);
			if (ret)
				dev_err(&pdev->dev,
					"couldn't create usr_rst_sw_dis\n");

			usr_rst_sw_dis_flg = 0;

			ret = device_create_file(&pdev->dev,
						&dev_attr_fac_kill_sw_dis);
			if (ret)
				dev_err(&pdev->dev,
					"couldn't create fac_kill_sw_dis\n");

			fac_kill_sw_dis_flg = 0;
		}

		info->warn_irq = gpio_to_irq(info->list[KP_WARN_INDEX].gpio);
		info->fac_cbl_irq =
			gpio_to_irq(info->list[KP_CABLE_INDEX].gpio);

		INIT_DELAYED_WORK(&info->warn_irq_work, warn_irq_w);
		INIT_DELAYED_WORK(&info->fac_cbl_irq_work, fac_cbl_irq_w);

		if (info->warn_irq) {
			ret = request_irq(info->warn_irq,
					  warn_irq_handler,
					  IRQF_TRIGGER_FALLING,
					  "mmi_factory_warn", info);
			if (ret) {
				dev_err(&pdev->dev,
					"request irq failed for Warn\n");
				goto fail;
			}
		} else {
			ret = -ENODEV;
			dev_err(&pdev->dev, "IRQ for Warn doesn't exist\n");
			goto fail;
		}

		if (info->fac_cbl_irq) {
			ret = request_irq(info->fac_cbl_irq,
					  fac_cbl_irq_handler,
					  IRQF_TRIGGER_RISING |
					  IRQF_TRIGGER_FALLING,
					  "mmi_factory_fac_cbl", info);
			if (ret) {
				dev_err(&pdev->dev,
					"irq failed for Factory Cable\n");
				goto remove_warn;
			}
		} else {
			ret = -ENODEV;
			dev_err(&pdev->dev,
				"IRQ for Factory Cable doesn't exist\n");
			goto remove_warn;
		}
	}

	platform_set_drvdata(pdev, info);

	return 0;

remove_warn:
	free_irq(info->warn_irq, info);
fail:
	gpio_free_array(info->list, info->num_gpios);
	return ret;
}