dm thin metadata: fix __udivdi3 undefined on 32-bit
[linux/fpc-iii.git] / drivers / staging / fbtft / fbtft-sysfs.c
blob8d8bd12b90a1d33bcc97fb7f4f6dc3d869078da6
1 #include "fbtft.h"
2 #include "internal.h"
4 static int get_next_ulong(char **str_p, unsigned long *val, char *sep, int base)
6 char *p_val;
7 int ret;
9 if (!str_p || !(*str_p))
10 return -EINVAL;
12 p_val = strsep(str_p, sep);
14 if (!p_val)
15 return -EINVAL;
17 ret = kstrtoul(p_val, base, val);
18 if (ret)
19 return -EINVAL;
21 return 0;
24 int fbtft_gamma_parse_str(struct fbtft_par *par, unsigned long *curves,
25 const char *str, int size)
27 char *str_p, *curve_p = NULL;
28 char *tmp;
29 unsigned long val = 0;
30 int ret = 0;
31 int curve_counter, value_counter;
33 fbtft_par_dbg(DEBUG_SYSFS, par, "%s() str=\n", __func__);
35 if (!str || !curves)
36 return -EINVAL;
38 fbtft_par_dbg(DEBUG_SYSFS, par, "%s\n", str);
40 tmp = kmemdup(str, size + 1, GFP_KERNEL);
41 if (!tmp)
42 return -ENOMEM;
44 /* replace optional separators */
45 str_p = tmp;
46 while (*str_p) {
47 if (*str_p == ',')
48 *str_p = ' ';
49 if (*str_p == ';')
50 *str_p = '\n';
51 str_p++;
54 str_p = strim(tmp);
56 curve_counter = 0;
57 while (str_p) {
58 if (curve_counter == par->gamma.num_curves) {
59 dev_err(par->info->device, "Gamma: Too many curves\n");
60 ret = -EINVAL;
61 goto out;
63 curve_p = strsep(&str_p, "\n");
64 value_counter = 0;
65 while (curve_p) {
66 if (value_counter == par->gamma.num_values) {
67 dev_err(par->info->device,
68 "Gamma: Too many values\n");
69 ret = -EINVAL;
70 goto out;
72 ret = get_next_ulong(&curve_p, &val, " ", 16);
73 if (ret)
74 goto out;
75 curves[curve_counter * par->gamma.num_values + value_counter] = val;
76 value_counter++;
78 if (value_counter != par->gamma.num_values) {
79 dev_err(par->info->device, "Gamma: Too few values\n");
80 ret = -EINVAL;
81 goto out;
83 curve_counter++;
85 if (curve_counter != par->gamma.num_curves) {
86 dev_err(par->info->device, "Gamma: Too few curves\n");
87 ret = -EINVAL;
88 goto out;
91 out:
92 kfree(tmp);
93 return ret;
96 static ssize_t
97 sprintf_gamma(struct fbtft_par *par, unsigned long *curves, char *buf)
99 ssize_t len = 0;
100 unsigned int i, j;
102 mutex_lock(&par->gamma.lock);
103 for (i = 0; i < par->gamma.num_curves; i++) {
104 for (j = 0; j < par->gamma.num_values; j++)
105 len += scnprintf(&buf[len], PAGE_SIZE,
106 "%04lx ", curves[i * par->gamma.num_values + j]);
107 buf[len - 1] = '\n';
109 mutex_unlock(&par->gamma.lock);
111 return len;
114 static ssize_t store_gamma_curve(struct device *device,
115 struct device_attribute *attr,
116 const char *buf, size_t count)
118 struct fb_info *fb_info = dev_get_drvdata(device);
119 struct fbtft_par *par = fb_info->par;
120 unsigned long tmp_curves[FBTFT_GAMMA_MAX_VALUES_TOTAL];
121 int ret;
123 ret = fbtft_gamma_parse_str(par, tmp_curves, buf, count);
124 if (ret)
125 return ret;
127 ret = par->fbtftops.set_gamma(par, tmp_curves);
128 if (ret)
129 return ret;
131 mutex_lock(&par->gamma.lock);
132 memcpy(par->gamma.curves, tmp_curves,
133 par->gamma.num_curves * par->gamma.num_values * sizeof(tmp_curves[0]));
134 mutex_unlock(&par->gamma.lock);
136 return count;
139 static ssize_t show_gamma_curve(struct device *device,
140 struct device_attribute *attr, char *buf)
142 struct fb_info *fb_info = dev_get_drvdata(device);
143 struct fbtft_par *par = fb_info->par;
145 return sprintf_gamma(par, par->gamma.curves, buf);
148 static struct device_attribute gamma_device_attrs[] = {
149 __ATTR(gamma, 0660, show_gamma_curve, store_gamma_curve),
152 void fbtft_expand_debug_value(unsigned long *debug)
154 switch (*debug & 0x7) {
155 case 1:
156 *debug |= DEBUG_LEVEL_1;
157 break;
158 case 2:
159 *debug |= DEBUG_LEVEL_2;
160 break;
161 case 3:
162 *debug |= DEBUG_LEVEL_3;
163 break;
164 case 4:
165 *debug |= DEBUG_LEVEL_4;
166 break;
167 case 5:
168 *debug |= DEBUG_LEVEL_5;
169 break;
170 case 6:
171 *debug |= DEBUG_LEVEL_6;
172 break;
173 case 7:
174 *debug = 0xFFFFFFFF;
175 break;
179 static ssize_t store_debug(struct device *device,
180 struct device_attribute *attr,
181 const char *buf, size_t count)
183 struct fb_info *fb_info = dev_get_drvdata(device);
184 struct fbtft_par *par = fb_info->par;
185 int ret;
187 ret = kstrtoul(buf, 10, &par->debug);
188 if (ret)
189 return ret;
190 fbtft_expand_debug_value(&par->debug);
192 return count;
195 static ssize_t show_debug(struct device *device,
196 struct device_attribute *attr, char *buf)
198 struct fb_info *fb_info = dev_get_drvdata(device);
199 struct fbtft_par *par = fb_info->par;
201 return snprintf(buf, PAGE_SIZE, "%lu\n", par->debug);
204 static struct device_attribute debug_device_attr = \
205 __ATTR(debug, 0660, show_debug, store_debug);
207 void fbtft_sysfs_init(struct fbtft_par *par)
209 device_create_file(par->info->dev, &debug_device_attr);
210 if (par->gamma.curves && par->fbtftops.set_gamma)
211 device_create_file(par->info->dev, &gamma_device_attrs[0]);
214 void fbtft_sysfs_exit(struct fbtft_par *par)
216 device_remove_file(par->info->dev, &debug_device_attr);
217 if (par->gamma.curves && par->fbtftops.set_gamma)
218 device_remove_file(par->info->dev, &gamma_device_attrs[0]);