1 // SPDX-License-Identifier: GPL-2.0
5 static int get_next_ulong(char **str_p, unsigned long *val, char *sep, int base)
9 if (!str_p || !(*str_p))
12 p_val = strsep(str_p, sep);
17 return kstrtoul(p_val, base, val);
20 int fbtft_gamma_parse_str(struct fbtft_par *par, u32 *curves,
21 const char *str, int size)
23 char *str_p, *curve_p = NULL;
25 unsigned long val = 0;
27 int curve_counter, value_counter;
30 fbtft_par_dbg(DEBUG_SYSFS, par, "%s() str=\n", __func__);
35 fbtft_par_dbg(DEBUG_SYSFS, par, "%s\n", str);
37 tmp = kmemdup(str, size + 1, GFP_KERNEL);
41 /* replace optional separators */
55 if (curve_counter == par->gamma.num_curves) {
56 dev_err(par->info->device, "Gamma: Too many curves\n");
60 curve_p = strsep(&str_p, "\n");
63 if (value_counter == par->gamma.num_values) {
64 dev_err(par->info->device,
65 "Gamma: Too many values\n");
69 ret = get_next_ulong(&curve_p, &val, " ", 16);
73 _count = curve_counter * par->gamma.num_values +
78 if (value_counter != par->gamma.num_values) {
79 dev_err(par->info->device, "Gamma: Too few values\n");
85 if (curve_counter != par->gamma.num_curves) {
86 dev_err(par->info->device, "Gamma: Too few curves\n");
97 sprintf_gamma(struct fbtft_par *par, u32 *curves, char *buf)
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 "%04x ", curves[i * par->gamma.num_values + j]);
109 mutex_unlock(&par->gamma.lock);
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 u32 tmp_curves[FBTFT_GAMMA_MAX_VALUES_TOTAL];
123 ret = fbtft_gamma_parse_str(par, tmp_curves, buf, count);
127 ret = par->fbtftops.set_gamma(par, tmp_curves);
131 mutex_lock(&par->gamma.lock);
132 memcpy(par->gamma.curves, tmp_curves,
133 par->gamma.num_curves * par->gamma.num_values *
134 sizeof(tmp_curves[0]));
135 mutex_unlock(&par->gamma.lock);
140 static ssize_t show_gamma_curve(struct device *device,
141 struct device_attribute *attr, char *buf)
143 struct fb_info *fb_info = dev_get_drvdata(device);
144 struct fbtft_par *par = fb_info->par;
146 return sprintf_gamma(par, par->gamma.curves, buf);
149 static struct device_attribute gamma_device_attrs[] = {
150 __ATTR(gamma, 0660, show_gamma_curve, store_gamma_curve),
153 void fbtft_expand_debug_value(unsigned long *debug)
155 switch (*debug & 0x7) {
157 *debug |= DEBUG_LEVEL_1;
160 *debug |= DEBUG_LEVEL_2;
163 *debug |= DEBUG_LEVEL_3;
166 *debug |= DEBUG_LEVEL_4;
169 *debug |= DEBUG_LEVEL_5;
172 *debug |= DEBUG_LEVEL_6;
180 static ssize_t store_debug(struct device *device,
181 struct device_attribute *attr,
182 const char *buf, size_t count)
184 struct fb_info *fb_info = dev_get_drvdata(device);
185 struct fbtft_par *par = fb_info->par;
188 ret = kstrtoul(buf, 10, &par->debug);
191 fbtft_expand_debug_value(&par->debug);
196 static ssize_t show_debug(struct device *device,
197 struct device_attribute *attr, char *buf)
199 struct fb_info *fb_info = dev_get_drvdata(device);
200 struct fbtft_par *par = fb_info->par;
202 return sysfs_emit(buf, "%lu\n", par->debug);
205 static struct device_attribute debug_device_attr =
206 __ATTR(debug, 0660, show_debug, store_debug);
208 void fbtft_sysfs_init(struct fbtft_par *par)
210 device_create_file(par->info->dev, &debug_device_attr);
211 if (par->gamma.curves && par->fbtftops.set_gamma)
212 device_create_file(par->info->dev, &gamma_device_attrs[0]);
215 void fbtft_sysfs_exit(struct fbtft_par *par)
217 device_remove_file(par->info->dev, &debug_device_attr);
218 if (par->gamma.curves && par->fbtftops.set_gamma)
219 device_remove_file(par->info->dev, &gamma_device_attrs[0]);