linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Brownell <david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
To: Barry Song <21cnbao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Cc: dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
	dtor-JGs/UdohzUI@public.gmane.org,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
	spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
	linux-input-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	uclinux-dist-devel-ZG0+EudsQA8dtHy/vicBwGD2FQJk+8+b@public.gmane.org
Subject: Re: [PATCH 2/2] add ad714x input driver for button/scrollwhell/slider/touchpad
Date: Tue, 1 Sep 2009 18:51:30 -0700	[thread overview]
Message-ID: <200909011851.31383.david-b@pacbell.net> (raw)
In-Reply-To: <1251777330-16994-3-git-send-email-21cnbao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Monday 31 August 2009, Barry Song wrote:
> +
> +#define AD714x_SPI_ADDR        0x1C
> +#define AD714x_SPI_ADDR_SHFT   11
> +#define AD714x_SPI_READ        1
> +#define AD714x_SPI_READ_SHFT   10

Confusing; it is not an address but a fixed bit pattern
flagging command words.  Be less opaque; maybe

  #define AD714x_CMD_PREFIX       0xe000   /* bits 15:11 */
  #define AD714x_READ             BIT(10)


> +#if defined(CONFIG_INPUT_AD714X_SPI)
> +#define bus_device		struct spi_device
> +#elif defined(CONFIG_INPUT_AD714X_I2C)
> +#define bus_device		struct i2c_client
> +#else
> +#error Communication method needs to be selected (I2C or SPI)
> +#endif

Best to allow both interfaces in the same kernel, for build
tests and kernels that can run on more than one board.

The way that works in some contexts is to record

	struct device *dev;

(or somesuch) in the driver state struct and use it pretty much
everywhere (including dev_* messaging!) except bus-related code
which uses to_i2c_client() or to_spi_device() to get the right
pointer view.

And the (missing) Kconfig would depend on "SPI || I2C"; and this
driver would register (and unregister) either or both driver
facets depending on which were possible.  (Someone might even
provide stubs for the I2C=n or SPI=n cases, to let such drivers
avoid #ifdeffery.  Someday.)


> +	pr_debug("slider %d absolute position:%d\n", idx, sw->abs_pos);

You should use the dev_*() functions not pr_*().


> +#define RIGHT_END_POINT_DETECTION_LEVEL			750
> +#define LEFT_RIGHT_END_POINT_DEAVTIVALION_LEVEL		850
> +#define TOP_END_POINT_DETECTION_LEVEL			550
> +#define BOTTOM_END_POINT_DETECTION_LEVEL		950
> +#define TOP_BOTTOM_END_POINT_DEAVTIVALION_LEVEL		700
> +static int touchpad_check_endpoint(struct ad714x_chip *ad714x, int idx)
> +{

Here and elsewhere:  whitespace between CPP directives and
the Real Code (tm), please...


> +#define MAX_DEVICE_NUM 8
> +static int __devinit ad714x_probe(struct ad714x_chip *ad714x)
> +{
> +	int ret = 0;
> +	struct input_dev *input[MAX_DEVICE_NUM];
> +
> +	struct ad714x_driver_data *drv_data = NULL;
> +
> +	struct ad714x_button_plat *bt_plat   = ad714x->hw->button;
> +	struct ad714x_slider_plat *sd_plat   = ad714x->hw->slider;
> +	struct ad714x_wheel_plat *wl_plat    = ad714x->hw->wheel;
> +	struct ad714x_touchpad_plat *tp_plat = ad714x->hw->touchpad;
> +
> +	struct ad714x_button_drv *bt_drv   = NULL;
> +	struct ad714x_slider_drv *sd_drv   = NULL;
> +	struct ad714x_wheel_drv *wl_drv    = NULL;
> +	struct ad714x_touchpad_drv *tp_drv = NULL;
> +
> +	int alloc_idx = 0, reg_idx = 0;
> +	int i;
> +
> +	ret = ad714x_hw_detect(ad714x);
> +	if (ret)
> +		goto det_err;
> +
> +	/*
> +	 * Allocate and register AD714x input device
> +	 */
> +
> +	drv_data = kzalloc(sizeof(struct ad714x_driver_data), GFP_KERNEL);

drv_data is not an input device.


> +	if (!drv_data) {
> +		dev_err(&ad714x->bus->dev,
> +			"Can't allocate memory for ad714x driver info\n");
> +		ret = -ENOMEM;
> +		goto fail_alloc_reg;
> +	}
> +	ad714x->sw = drv_data;
> +
> +	/* a slider uses one input_dev instance */
> +	if (ad714x->hw->slider_num > 0) {
> +		sd_drv = kzalloc(sizeof(struct ad714x_slider_drv) *
> +				ad714x->hw->slider_num, GFP_KERNEL);
> +		if (!sd_drv) {
> +			dev_err(&ad714x->bus->dev,
> +				"Can't allocate memory for slider info\n");
> +			ret = -ENOMEM;
> +			goto fail_alloc_reg;
> +		}
> +
> +		for (i = 0; i < ad714x->hw->slider_num; i++) {
> +			input[alloc_idx] = input_allocate_device();
> +			if (!input[alloc_idx]) {
> +				dev_err(&ad714x->bus->dev,
> +				"Can't allocate input device %d\n", alloc_idx);
> +				ret = -ENOMEM;
> +				goto fail_alloc_reg;
> +			}
> +			alloc_idx++;
> +
> +			__set_bit(EV_ABS, input[alloc_idx-1]->evbit);
> +			__set_bit(ABS_X, input[alloc_idx-1]->absbit);
> +			__set_bit(ABS_PRESSURE, input[alloc_idx-1]->absbit);
> +			input_set_abs_params(input[alloc_idx-1], ABS_X, 0,
> +					sd_plat->max_coord, 0, 0);
> +			input_set_abs_params(input[alloc_idx-1], ABS_PRESSURE,
> +				0, 1, 0, 0);
> +
> +			input[alloc_idx-1]->id.bustype = BUS_I2C;

This could be SPI instead... and there are some fields you
forgot to set.  Like the ones putting this into the device tree
in the right spot, and some identifiers...

Take that bus type code as an input param to this function.


> +
> +			ret = input_register_device(input[reg_idx]);
> +			if (ret) {
> +				dev_err(&ad714x->bus->dev,
> +				"Failed to register AD714x input device!\n");
> +				goto fail_alloc_reg;
> +			}
> +			reg_idx++;
> +
> +			sd_drv[i].input = input[alloc_idx-1];
> +			ad714x->sw->slider = sd_drv;
> +		}
> +	}
> +
> +	/* a wheel uses one input_dev instance */
> +	if (ad714x->hw->wheel_num > 0) {
> +		wl_drv = kzalloc(sizeof(struct ad714x_wheel_drv) *
> +				ad714x->hw->wheel_num, GFP_KERNEL);
> +		if (!wl_drv) {
> +			dev_err(&ad714x->bus->dev,
> +				"Can't allocate memory for wheel info\n");
> +			ret = -ENOMEM;
> +			goto fail_alloc_reg;
> +		}
> +
> +		for (i = 0; i < ad714x->hw->wheel_num; i++) {
> +			input[alloc_idx] = input_allocate_device();
> +			if (!input[alloc_idx]) {
> +				dev_err(&ad714x->bus->dev,
> +				"Can't allocate input device %d\n", alloc_idx);
> +				ret = -ENOMEM;
> +				goto fail_alloc_reg;
> +			}
> +			alloc_idx++;
> +
> +			__set_bit(EV_ABS, input[alloc_idx-1]->evbit);
> +			__set_bit(ABS_WHEEL, input[alloc_idx-1]->absbit);
> +			__set_bit(ABS_PRESSURE, input[alloc_idx-1]->absbit);
> +			input_set_abs_params(input[alloc_idx-1], ABS_WHEEL, 0,
> +					wl_plat->max_coord, 0, 0);
> +			input_set_abs_params(input[alloc_idx-1], ABS_PRESSURE,
> +				0, 1, 0, 0);
> +
> +			input[alloc_idx-1]->id.bustype = BUS_I2C;

Same as above:  it's not necessarily I2C, and there are important
fields left uninitialized.  Probably worth abstracting that setup
into some kind of helper.


> +
> +			ret = input_register_device(input[reg_idx]);
> +			if (ret) {
> +				dev_err(&ad714x->bus->dev,
> +				"Failed to register AD714x input device!\n");
> +				goto fail_alloc_reg;
> +			}
> +			reg_idx++;
> +
> +			wl_drv[i].input = input[alloc_idx-1];
> +			ad714x->sw->wheel = wl_drv;
> +		}
> +	}
> +
> +	/* a touchpad uses one input_dev instance */
> +	if (ad714x->hw->touchpad_num > 0) {
> +		tp_drv = kzalloc(sizeof(struct ad714x_touchpad_drv) *
> +				ad714x->hw->touchpad_num, GFP_KERNEL);
> +		if (!tp_drv) {
> +			dev_err(&ad714x->bus->dev,
> +				"Can't allocate memory for touchpad info\n");
> +			ret = -ENOMEM;
> +			goto fail_alloc_reg;
> +		}
> +
> +		for (i = 0; i < ad714x->hw->touchpad_num; i++) {
> +			input[alloc_idx] = input_allocate_device();
> +			if (!input[alloc_idx]) {
> +				dev_err(&ad714x->bus->dev,
> +					"Can't allocate input device %d\n",
> +					alloc_idx);
> +				ret = -ENOMEM;
> +				goto fail_alloc_reg;
> +			}
> +			alloc_idx++;
> +
> +			__set_bit(EV_ABS, input[alloc_idx-1]->evbit);
> +			__set_bit(ABS_X, input[alloc_idx-1]->absbit);
> +			__set_bit(ABS_Y, input[alloc_idx-1]->absbit);
> +			__set_bit(ABS_PRESSURE, input[alloc_idx-1]->absbit);
> +			input_set_abs_params(input[alloc_idx-1], ABS_X, 0,
> +					tp_plat->x_max_coord, 0, 0);
> +			input_set_abs_params(input[alloc_idx-1], ABS_Y, 0,
> +					tp_plat->y_max_coord, 0, 0);
> +			input_set_abs_params(input[alloc_idx-1], ABS_PRESSURE,
> +				0, 1, 0, 0);
> +
> +			input[alloc_idx-1]->id.bustype = BUS_I2C;

Again with the I2C-only and incomplete setup...


> +
> +			ret = input_register_device(input[reg_idx]);
> +			if (ret) {
> +				dev_err(&ad714x->bus->dev,
> +				"Failed to register AD714x input device!\n");
> +				goto fail_alloc_reg;
> +			}
> +			reg_idx++;
> +
> +			tp_drv[i].input = input[alloc_idx-1];
> +			ad714x->sw->touchpad = tp_drv;
> +		}
> +	}
> +
> +	/* all buttons use one input node */
> +	if (ad714x->hw->button_num > 0) {
> +		bt_drv = kzalloc(sizeof(struct ad714x_button_drv) *
> +				ad714x->hw->button_num, GFP_KERNEL);
> +		if (!bt_drv) {
> +			dev_err(&ad714x->bus->dev,
> +				"Can't allocate memory for button info\n");
> +			ret = -ENOMEM;
> +			goto fail_alloc_reg;
> +		}
> +
> +		input[alloc_idx] = input_allocate_device();
> +		if (!input[alloc_idx]) {
> +			dev_err(&ad714x->bus->dev,
> +					"Can't allocate input device %d\n",
> +					alloc_idx);
> +			ret = -ENOMEM;
> +			goto fail_alloc_reg;
> +		}
> +		alloc_idx++;
> +
> +		__set_bit(EV_KEY, input[alloc_idx-1]->evbit);
> +		for (i = 0; i < ad714x->hw->button_num; i++) {
> +			__set_bit(bt_plat[i].keycode,
> +				input[alloc_idx-1]->keybit);
> +		}
> +
> +		input[alloc_idx-1]->id.bustype = BUS_I2C;

... and again ...


> +
> +		ret = input_register_device(input[reg_idx]);
> +		if (ret) {
> +			dev_err(&ad714x->bus->dev,
> +				"Failed to register AD714x input device!\n");
> +			goto fail_alloc_reg;
> +		}
> +		reg_idx++;
> +
> +		for (i = 0; i < ad714x->hw->button_num; i++)
> +			bt_drv[i].input = input[alloc_idx-1];
> +		ad714x->sw->button = bt_drv;
> +	}
> +
> +	/* initilize and request sw/hw resources */
> +
> +	ad714x_hw_init(ad714x);
> +	mutex_init(&ad714x->mutex);
> +
> +	if (ad714x->bus->irq > 0) {
> +		ret = request_threaded_irq(ad714x->bus->irq, ad714x_interrupt,
> +				ad714x_interrupt_thread, IRQF_TRIGGER_FALLING,
> +				"ad714x_captouch", ad714x);
> +		if (ret) {
> +			dev_err(&ad714x->bus->dev, "Can't allocate irq %d\n",
> +					ad714x->bus->irq);
> +			goto fail_irq;
> +		}
> +	} else
> +		dev_warn(&ad714x->bus->dev, "IRQ not configured!\n");
> +
> +	return 0;
> +
> +fail_irq:
> +fail_alloc_reg:
> +	for (i = 0; i < reg_idx; i++)
> +		input_unregister_device(input[i]);
> +	for (i = 0; i < alloc_idx; i++)
> +		input_free_device(input[i]);
> +	kfree(bt_drv); /* kfree(NULL) is safe check is not required */
> +	kfree(sd_drv);
> +	kfree(wl_drv);
> +	kfree(tp_drv);
> +	kfree(drv_data);
> +det_err:
> +	return ret;
> +}
> +
> +
> +static const struct i2c_device_id ad714x_id[] = {
> +	{ "ad714x_captouch", 0 },

Plain old "ad714x" please.  Though it might be
better to see "ad7147" and "ad7142" separately;
this doesn't work for the ad7143 and ad7148 too,
does it?  Do you know if it will work for as-yet
undefined (I think) ad714[014569] chips?


> +	{ }
> +};
> +MODULE_DEVICE_TABLE(i2c, ad714x_id);

  parent reply	other threads:[~2009-09-02  1:51 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-01  3:55 [PATCH 0/2] add ad714x captouch sensor input driver Barry Song
2009-09-01  3:55 ` [PATCH 1/2] add ad714x platform_data definition Barry Song
2009-09-01  3:55   ` [PATCH 2/2] add ad714x input driver for button/scrollwhell/slider/touchpad Barry Song
     [not found]     ` <1251777330-16994-3-git-send-email-21cnbao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2009-09-01 19:30       ` Mike Frysinger
     [not found]         ` <8bd0f97a0909011230r50cb532ep46db64d65cbb49e5-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-09-02  2:04           ` [Uclinux-dist-devel] " David Brownell
2009-09-02  2:46         ` [Uclinux-dist-devel] [PATCH 2/2] add ad714x input driver forbutton/scrollwhell/slider/touchpad Song, Barry
2009-09-02  3:09           ` Mike Frysinger
2009-09-02  3:17             ` Song, Barry
2009-09-02  9:50               ` [Uclinux-dist-devel] [PATCH 2/2] add ad714x input driverforbutton/scrollwhell/slider/touchpad Robin Getz
2009-09-02  9:48                 ` Mike Frysinger
     [not found]           ` <0F1B54C89D5F954D8535DB252AF412FA04A5CADA-SGdA1W8gREmuVPpjEGsWsTcYPEmu4y7e@public.gmane.org>
2009-09-02  4:31             ` [Uclinux-dist-devel] [PATCH 2/2] add ad714x input driver forbutton/scrollwhell/slider/touchpad David Brownell
2009-09-02  7:51               ` Barry Song
2009-09-02  8:37                 ` Song, Barry
2009-09-02  8:41                 ` David Brownell
2009-09-02  1:51       ` David Brownell [this message]
2009-09-02  6:26         ` Song, Barry
2009-09-08  6:34     ` [PATCH 2/2] add ad714x input driver for button/scrollwhell/slider/touchpad Dmitry Torokhov
2009-09-08  6:48       ` [Uclinux-dist-devel] [PATCH 2/2] add ad714x input driverfor button/scrollwhell/slider/touchpad Song, Barry
2009-09-01 18:41   ` [Uclinux-dist-devel] [PATCH 1/2] add ad714x platform_data definition Mike Frysinger
2009-09-02  2:09     ` [Uclinux-dist-devel] [PATCH 1/2] add ad714x platform_datadefinition Song, Barry
     [not found]   ` <1251777330-16994-2-git-send-email-21cnbao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2009-09-02  1:57     ` [PATCH 1/2] add ad714x platform_data definition David Brownell
2009-09-02  4:47       ` [Uclinux-dist-devel] [PATCH 1/2] add ad714x platform_datadefinition Song, Barry
     [not found]         ` <0F1B54C89D5F954D8535DB252AF412FA04A96A41-SGdA1W8gREmuVPpjEGsWsTcYPEmu4y7e@public.gmane.org>
2009-09-02  5:14           ` David Brownell
2009-09-02  5:24             ` [Uclinux-dist-devel] " Song, Barry
2009-09-02 12:16       ` [spi-devel-general] [PATCH 1/2] add ad714x platform_data definition Bill Gatliff
2009-09-01 18:46 ` [Uclinux-dist-devel] [PATCH 0/2] add ad714x captouch sensor input driver Mike Frysinger
     [not found]   ` <8bd0f97a0909011146t210cbacbx6b0fa323242ac3d3-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-09-02  1:52     ` David Brownell
2009-09-02  2:08   ` [Uclinux-dist-devel] [PATCH 0/2] add ad714x captouch sensorinput driver Song, Barry

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200909011851.31383.david-b@pacbell.net \
    --to=david-b-ybekhbn/0ldr7s880joybq@public.gmane.org \
    --cc=21cnbao-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=dtor-JGs/UdohzUI@public.gmane.org \
    --cc=linux-input-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=uclinux-dist-devel-ZG0+EudsQA8dtHy/vicBwGD2FQJk+8+b@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).