2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 * Copyright (C) 2008,2009 by Openmoko, Inc.
17 * Author: Nelson Castillo <arhuaco@freaks-unidos.net>
18 * All rights reserved.
20 * Linearly scale touchscreen values.
22 * Expose the TS_FILTER_LINEAR_NCONSTANTS for the linear transformation
27 #include <linux/kernel.h>
28 #include <linux/slab.h>
29 #include <linux/string.h>
31 #include <linux/touchscreen/ts_filter_linear.h>
33 struct ts_filter_linear;
38 /* The actual private object. */
39 struct ts_filter_linear *tsfl;
44 #define to_const_obj(x) container_of(x, struct const_obj, kobj)
46 struct const_attribute {
47 struct attribute attr;
48 ssize_t (*show)(struct const_obj *const, struct const_attribute *attr,
50 ssize_t (*store)(struct const_obj *const, struct const_attribute *attr,
51 const char *buf, size_t count);
54 #define to_const_attr(x) container_of(x, struct const_attribute, attr)
57 /* Private linear filter structure. */
59 struct ts_filter_linear {
60 /* Private configuration for this filter. */
61 struct ts_filter_linear_configuration *config;
63 /* Generic filter API. */
66 /* Linear constants for the transformation. */
67 int constants[TS_FILTER_LINEAR_NCONSTANTS];
71 /* Our const_object. */
72 struct const_obj c_obj;
73 /* Our type. We will stick operations to it. */
74 struct kobj_type const_ktype;
75 /* Attrs. of the virtual files. */
76 struct const_attribute kattrs[TS_FILTER_LINEAR_NCONSTANTS];
77 /* Default Attrs. Always NULL for us. */
78 struct attribute *attrs[TS_FILTER_LINEAR_NCONSTANTS + 1];
79 /* Storage for the name of the virtual files. */
80 char attr_names[TS_FILTER_LINEAR_NCONSTANTS][2];
83 #define ts_filter_to_filter_linear(f) \
84 container_of(f, struct ts_filter_linear, tsf)
86 /* Sysfs functions. */
88 static ssize_t const_attr_show(struct kobject *kobj,
89 struct attribute *attr,
92 struct const_attribute *a = to_const_attr(attr);
94 return a->show(to_const_obj(kobj), a, buf);
97 static ssize_t const_attr_store(struct kobject *kobj,
98 struct attribute *attr,
99 const char *buf, size_t len)
101 struct const_attribute *a = to_const_attr(attr);
103 return a->store(to_const_obj(kobj), a, buf, len);
106 static struct sysfs_ops const_sysfs_ops = {
107 .show = const_attr_show,
108 .store = const_attr_store,
111 static void const_release(struct kobject *kobj)
113 kfree(to_const_obj(kobj)->tsfl);
116 static ssize_t const_show(struct const_obj *obj, struct const_attribute *attr,
121 sscanf(attr->attr.name, "%d", &who);
122 return sprintf(buf, "%d\n", obj->tsfl->constants[who]);
125 static ssize_t const_store(struct const_obj *obj, struct const_attribute *attr,
126 const char *buf, size_t count)
130 sscanf(attr->attr.name, "%d", &who);
131 sscanf(buf, "%d", &obj->tsfl->constants[who]);
135 /* Filter functions. */
137 static struct ts_filter *ts_filter_linear_create(
138 struct platform_device *pdev,
139 const struct ts_filter_configuration *conf,
142 struct ts_filter_linear *tsfl;
146 tsfl = kzalloc(sizeof(struct ts_filter_linear), GFP_KERNEL);
150 tsfl->config = container_of(conf,
151 struct ts_filter_linear_configuration,
154 tsfl->tsf.count_coords = count_coords;
156 for (i = 0; i < TS_FILTER_LINEAR_NCONSTANTS; ++i) {
157 tsfl->constants[i] = tsfl->config->constants[i];
160 sprintf(tsfl->attr_names[i], "%d", i);
161 tsfl->kattrs[i].attr.name = tsfl->attr_names[i];
162 tsfl->kattrs[i].attr.mode = 0666;
163 tsfl->kattrs[i].show = const_show;
164 tsfl->kattrs[i].store = const_store;
165 tsfl->attrs[i] = &tsfl->kattrs[i].attr;
167 tsfl->attrs[i] = NULL;
169 tsfl->const_ktype.sysfs_ops = &const_sysfs_ops;
170 tsfl->const_ktype.release = const_release;
171 tsfl->const_ktype.default_attrs = tsfl->attrs;
172 tsfl->c_obj.tsfl = tsfl; /* kernel frees tsfl in const_release */
174 ret = kobject_init_and_add(&tsfl->c_obj.kobj, &tsfl->const_ktype,
175 &pdev->dev.kobj, "calibration");
177 kobject_put(&tsfl->c_obj.kobj);
181 dev_info(&pdev->dev, "Created Linear filter coords:%d\n", count_coords);
186 static void ts_filter_linear_destroy(struct ts_filter *tsf)
188 struct ts_filter_linear *tsfl = ts_filter_to_filter_linear(tsf);
190 /* Kernel frees tsfl in const_release. */
191 kobject_put(&tsfl->c_obj.kobj);
194 static void ts_filter_linear_scale(struct ts_filter *tsf, int *coords)
196 struct ts_filter_linear *tsfl = ts_filter_to_filter_linear(tsf);
198 int *k = tsfl->constants;
199 int c0 = coords[tsfl->config->coord0];
200 int c1 = coords[tsfl->config->coord1];
202 coords[tsfl->config->coord0] = (k[2] + k[0] * c0 + k[1] * c1) / k[6];
203 coords[tsfl->config->coord1] = (k[5] + k[3] * c0 + k[4] * c1) / k[6];
206 const struct ts_filter_api ts_filter_linear_api = {
207 .create = ts_filter_linear_create,
208 .destroy = ts_filter_linear_destroy,
209 .scale = ts_filter_linear_scale,
211 EXPORT_SYMBOL_GPL(ts_filter_linear_api);