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 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 "ts_filter_linear.h"
28 #include <linux/kernel.h>
29 #include <linux/slab.h>
30 #include <linux/string.h>
36 static ssize_t
const_attr_show(struct kobject
*kobj
,
37 struct attribute
*attr
,
40 struct const_attribute
*a
= to_const_attr(attr
);
42 return a
->show(to_const_obj(kobj
), a
, buf
);
45 static ssize_t
const_attr_store(struct kobject
*kobj
,
46 struct attribute
*attr
,
47 const char *buf
, size_t len
)
49 struct const_attribute
*a
= to_const_attr(attr
);
51 return a
->store(to_const_obj(kobj
), a
, buf
, len
);
54 static struct sysfs_ops const_sysfs_ops
= {
55 .show
= const_attr_show
,
56 .store
= const_attr_store
,
59 static void const_release(struct kobject
*kobj
)
61 kfree(to_const_obj(kobj
)->tsfl
);
64 static ssize_t
const_show(struct const_obj
*obj
, struct const_attribute
*attr
,
69 sscanf(attr
->attr
.name
, "%d", &who
);
70 return sprintf(buf
, "%d\n", obj
->tsfl
->constants
[who
]);
73 static ssize_t
const_store(struct const_obj
*obj
, struct const_attribute
*attr
,
74 const char *buf
, size_t count
)
78 sscanf(attr
->attr
.name
, "%d", &who
);
79 sscanf(buf
, "%d", &obj
->tsfl
->constants
[who
]);
83 /* filter functions */
85 static struct ts_filter
*ts_filter_linear_create(struct platform_device
*pdev
,
86 void *conf
, int count_coords
)
88 struct ts_filter_linear
*tsfl
;
92 tsfl
= kzalloc(sizeof(struct ts_filter_linear
), GFP_KERNEL
);
96 tsfl
->config
= (struct ts_filter_linear_configuration
*)conf
;
97 tsfl
->tsf
.count_coords
= count_coords
;
99 for (i
= 0; i
< TS_FILTER_LINEAR_NCONSTANTS
; ++i
) {
100 tsfl
->constants
[i
] = tsfl
->config
->constants
[i
];
103 sprintf(tsfl
->attr_names
[i
], "%d", i
);
104 tsfl
->kattrs
[i
].attr
.name
= tsfl
->attr_names
[i
];
105 tsfl
->kattrs
[i
].attr
.mode
= 0666;
106 tsfl
->kattrs
[i
].show
= const_show
;
107 tsfl
->kattrs
[i
].store
= const_store
;
108 tsfl
->attrs
[i
] = &tsfl
->kattrs
[i
].attr
;
110 tsfl
->attrs
[i
] = NULL
;
112 tsfl
->const_ktype
.sysfs_ops
= &const_sysfs_ops
;
113 tsfl
->const_ktype
.release
= const_release
;
114 tsfl
->const_ktype
.default_attrs
= tsfl
->attrs
;
115 tsfl
->c_obj
.tsfl
= tsfl
; /* kernel frees tsfl in const_release */
117 ret
= kobject_init_and_add(&tsfl
->c_obj
.kobj
, &tsfl
->const_ktype
,
118 &pdev
->dev
.kobj
, "calibration");
120 kobject_put(&tsfl
->c_obj
.kobj
);
124 printk(KERN_INFO
" Created Linear ts filter depth %d\n", count_coords
);
129 static void ts_filter_linear_destroy(struct platform_device
*pdev
,
130 struct ts_filter
*tsf
)
132 struct ts_filter_linear
*tsfl
= (struct ts_filter_linear
*)tsf
;
134 /* kernel frees tsfl in const_release */
135 kobject_put(&tsfl
->c_obj
.kobj
);
138 static void ts_filter_linear_clear(struct ts_filter
*tsf
)
140 if (tsf
->next
) /* chain */
141 (tsf
->next
->api
->clear
)(tsf
->next
);
145 static void ts_filter_linear_scale(struct ts_filter
*tsf
, int *coords
)
147 struct ts_filter_linear
*tsfl
= (struct ts_filter_linear
*)tsf
;
148 int *k
= tsfl
->constants
;
149 int c0
= coords
[tsfl
->config
->coord0
];
150 int c1
= coords
[tsfl
->config
->coord1
];
152 coords
[tsfl
->config
->coord0
] = (k
[2] + k
[0] * c0
+ k
[1] * c1
) / k
[6];
153 coords
[tsfl
->config
->coord1
] = (k
[5] + k
[3] * c0
+ k
[4] * c1
) / k
[6];
156 (tsf
->next
->api
->scale
)(tsf
->next
, coords
);
159 static int ts_filter_linear_process(struct ts_filter
*tsf
, int *coords
)
162 return (tsf
->next
->api
->process
)(tsf
->next
, coords
);
167 struct ts_filter_api ts_filter_linear_api
= {
168 .create
= ts_filter_linear_create
,
169 .destroy
= ts_filter_linear_destroy
,
170 .clear
= ts_filter_linear_clear
,
171 .process
= ts_filter_linear_process
,
172 .scale
= ts_filter_linear_scale
,