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
);