Esempio n. 1
0
static int __init fbtft_device_init(void)
{
	struct spi_master *master = NULL;
	struct spi_board_info *display = NULL;
	const struct fbtft_platform_data *pdata = NULL;
	const struct fbtft_gpio *gpio = NULL;
	char *p_name, *p_num;
	bool found = false;
	int i;
	long val;
	int ret = 0;

	pr_debug("\n\n"DRVNAME": init\n");

	/* parse module parameter: gpios */
	if (gpios_num > MAX_GPIOS) {
		pr_err(DRVNAME":  gpios parameter: exceeded max array size: %d\n", MAX_GPIOS);
		return -EINVAL;
	}
	if (gpios_num > 0) {
		for (i=0;i<gpios_num;i++) {
			if (strchr(gpios[i], ':') == NULL) {
				pr_err(DRVNAME":  error missing ':' in gpios parameter: %s\n", gpios[i]);
				return -EINVAL;
			}
			p_num = gpios[i];
			p_name = strsep(&p_num, ":");
			if (p_name == NULL || p_num == NULL) {
				pr_err(DRVNAME":  something bad happenned parsing gpios parameter: %s\n", gpios[i]);
				return -EINVAL;
			}
			ret = kstrtol(p_num, 10, &val);
			if (ret) {
				pr_err(DRVNAME":  could not parse number in gpios parameter: %s:%s\n", p_name, p_num);
				return -EINVAL;
			}
			strcpy(fbtft_device_param_gpios[i].name, p_name);
			fbtft_device_param_gpios[i].gpio = (int) val;
			pdata = &fbtft_device_param_pdata;
		}
	}

	if (verbose > 2)
		pr_spi_devices(); /* print list of registered SPI devices */

	if (verbose > 2)
		pr_p_devices(); /* print list of 'fb' platform devices */

	if (name == NULL) {
		pr_err(DRVNAME":  missing module parameter: 'name'\n");
		pr_err(DRVNAME":  Use 'modinfo -p "DRVNAME"' to get all parameters\n");
		return -EINVAL;
	}

	pr_debug(DRVNAME":  name='%s', busnum=%d, cs=%d\n", name, busnum, cs);

	if (rotate > 3) {
		pr_warning("argument 'rotate' illegal value: %d (0-3). Setting it to 0.\n", rotate);
		rotate = 0;
	}

	/* name=list lists all supported drivers */
	if (strncmp(name, "list", 32) == 0) {
		pr_info(DRVNAME":  Supported drivers:\n");
		for (i=0; i < ARRAY_SIZE(fbtft_device_spi_displays); i++) {
			pr_info(DRVNAME":      %s\n", fbtft_device_spi_displays[i].modalias);
		}
		for (i=0; i < ARRAY_SIZE(fbtft_device_pdev_displays); i++) {
			pr_info(DRVNAME":      %s\n", fbtft_device_pdev_displays[i].name);
		}
		return -ECANCELED;
	}

	/* see if it is a SPI device */
	for (i=0; i < ARRAY_SIZE(fbtft_device_spi_displays); i++) {
		if (strncmp(name, fbtft_device_spi_displays[i].modalias, 32) == 0) {
			master = spi_busnum_to_master(busnum);
			if (!master) {
				pr_err(DRVNAME":  spi_busnum_to_master(%d) returned NULL\n", busnum);
				return -EINVAL;
			}
			fbtft_device_delete(master, cs);      /* make sure it's available */
			display = &fbtft_device_spi_displays[i];
			display->chip_select = cs;
			display->bus_num = busnum;
			if (speed)
				display->max_speed_hz = speed;
			if (mode != -1)
				display->mode = mode;
			if (pdata)
				display->platform_data = pdata;
			pdata = display->platform_data;
			((struct fbtft_platform_data *)pdata)->rotate = rotate;
			((struct fbtft_platform_data *)pdata)->bgr = bgr;
			if (fps)
				((struct fbtft_platform_data *)pdata)->fps = fps;
			if (txbuflen)
				((struct fbtft_platform_data *)pdata)->txbuflen = txbuflen;
			spi_device = spi_new_device(master, display);
			put_device(&master->dev);
			if (!spi_device) {
				pr_err(DRVNAME":    spi_new_device() returned NULL\n");
				return -EPERM;
			}
			found = true;
			break;
		}
	}

	if (!found) {
		/* see if it is a platform_device */
		for (i=0; i < ARRAY_SIZE(fbtft_device_pdev_displays); i++) {
			if (strncmp(name, fbtft_device_pdev_displays[i].name, 32) == 0) {
				p_device = &fbtft_device_pdev_displays[i];
				ret = platform_device_register(p_device);
				if (ret < 0) {
					pr_err(DRVNAME":    platform_device_register() returned %d\n", ret);
					return ret;
				}
				if (pdata)
					p_device->dev.platform_data = (void *)pdata;
				pdata = p_device->dev.platform_data;
				((struct fbtft_platform_data *)pdata)->rotate = rotate;
				((struct fbtft_platform_data *)pdata)->bgr = bgr;
				if (fps)
					((struct fbtft_platform_data *)pdata)->fps = fps;
				if (txbuflen)
					((struct fbtft_platform_data *)pdata)->txbuflen = txbuflen;
				found = true;
				break;
			}
		}
	}

	if (!found) {
		pr_err(DRVNAME":  device not supported: '%s'\n", name);
		return -EINVAL;
	}

	if (verbose)
		pr_info(DRVNAME":  GPIOS used by '%s':\n", name);
	gpio = pdata->gpios;
	if (!gpio) {
		pr_err(DRVNAME":  gpio is unexspectedly empty\n");
		return -EINVAL;
	}
	while (verbose && gpio->name[0]) {
		pr_info(DRVNAME":    '%s' = GPIO%d\n", gpio->name, gpio->gpio);
		gpio++;
	}

	if (spi_device && (verbose > 1))
		pr_spi_devices();
	if (p_device && (verbose > 1))
		pr_p_devices();

	return 0;
}
Esempio n. 2
0
static int __init ads7846_device_init(void)
{
	struct spi_master *master;
	struct ads7846_platform_data *pdata = &pdata_ads7846_device;

	if (verbose)
		pr_info("\n\n"DRVNAME": %s()\n", __func__);

	if (gpio_pendown < 0) {
		pr_err(DRVNAME": Argument required: 'gpio_pendown'\n");
		return -EINVAL;
	}

	if (verbose > 1)
		pr_spi_devices(); /* print list of registered SPI devices */

	/* set SPI values */
	spi_ads7846_device.max_speed_hz = speed;
	spi_ads7846_device.bus_num = busnum;
	spi_ads7846_device.chip_select = cs;
	spi_ads7846_device.mode = mode;
	irq = irq ? : (GPIO_IRQ_START + gpio_pendown);
	spi_ads7846_device.irq = irq;

	/* set platform_data values */
	pdata->model = model;
	pdata->vref_delay_usecs = vref_delay_usecs;
	pdata->vref_mv = vref_mv;
	pdata->keep_vref_on = keep_vref_on;
	pdata->swap_xy = swap_xy;
	pdata->settle_delay_usecs = settle_delay_usecs;
	pdata->penirq_recheck_delay_usecs = penirq_recheck_delay_usecs;
	pdata->x_plate_ohms = x_plate_ohms;
	pdata->y_plate_ohms = y_plate_ohms;
	pdata->x_min = x_min;
	pdata->x_max = x_max;
	pdata->y_min = y_min;
	pdata->y_max = y_max;
	pdata->pressure_min = pressure_min;
	pdata->pressure_max = pressure_max;
	pdata->debounce_max = debounce_max;
	pdata->debounce_tol = debounce_tol;
	pdata->debounce_rep = debounce_rep;
	pdata->gpio_pendown = gpio_pendown;
	pdata->irq_flags = irq_flags;

	if (verbose) {
		pr_info(DRVNAME": Settings:\n");
		pr_pdata(model);
		pr_pdata(gpio_pendown);
		pr_pdata(swap_xy);
		pr_pdata(x_min);
		pr_pdata(x_max);
		pr_pdata(y_min);
		pr_pdata(y_max);
		pr_pdata(x_plate_ohms);
		pr_pdata(pressure_min);
		pr_pdata(pressure_max);
		pr_pdata(keep_vref_on);
		pr_pdata(vref_delay_usecs);
		pr_pdata(vref_mv);
		pr_pdata(settle_delay_usecs);
		pr_pdata(penirq_recheck_delay_usecs);
		pr_pdata(y_plate_ohms);
		pr_pdata(debounce_max);
		pr_pdata(debounce_tol);
		pr_pdata(debounce_rep);
	}

	master = spi_busnum_to_master(spi_ads7846_device.bus_num);
	if (!master) {
		pr_err(DRVNAME": spi_busnum_to_master(%d) returned NULL.\n", spi_ads7846_device.bus_num);
		return -EINVAL;
	}

	spidevices_delete(master, spi_ads7846_device.chip_select);      /* make sure it's available */

	ads7846_spi_device = spi_new_device(master, &spi_ads7846_device);
	put_device(&master->dev);
	if (!ads7846_spi_device) {
		pr_err(DRVNAME": spi_new_device() returned NULL\n");
		return -EPERM;
	}

	if (verbose)
		pr_spi_devices();

	return 0;
}