@@ -516,9 +516,136 @@ static EDT_ATTR(offset_y, S_IWUSR | S_IRUGO, NO_REGISTER, NO_REGISTER,
/* m06: range 20 to 80, m09: range 0 to 30, m12: range 1 to 255... */
static EDT_ATTR(threshold, S_IWUSR | S_IRUGO, WORK_REGISTER_THRESHOLD,
M09_REGISTER_THRESHOLD, EV_REGISTER_THRESHOLD, 0, 255);
-/* m06: range 3 to 14, m12: range 1 to 255 */
-static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO, WORK_REGISTER_REPORT_RATE,
- M12_REGISTER_REPORT_RATE, NO_REGISTER, 0, 255);
+
+static int edt_ft5x06_report_rate_get(struct edt_ft5x06_ts_data *tsdata)
+{
+ unsigned int val;
+ int error;
+
+ if (tsdata->reg_addr.reg_report_rate == NO_REGISTER)
+ return -EOPNOTSUPP;
+
+ error = regmap_read(tsdata->regmap, tsdata->reg_addr.reg_report_rate,
+ &val);
+ if (error)
+ return error;
+
+ if (tsdata->version == EDT_M06)
+ val *= 10;
+
+ if (val != tsdata->report_rate) {
+ dev_warn(&tsdata->client->dev,
+ "report-rate: read (%d) and stored value (%d) differ\n",
+ val, tsdata->report_rate);
+ tsdata->report_rate = val;
+ }
+
+ return 0;
+}
+
+static ssize_t report_rate_show(struct device *dev,
+ struct device_attribute *dattr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+ size_t count;
+ int error;
+
+ mutex_lock(&tsdata->mutex);
+
+ if (tsdata->factory_mode) {
+ error = -EIO;
+ goto out;
+ }
+
+ error = edt_ft5x06_report_rate_get(tsdata);
+ if (error) {
+ dev_err(&tsdata->client->dev,
+ "Failed to fetch attribute %s, error %d\n",
+ dattr->attr.name, error);
+ goto out;
+ }
+
+ count = sysfs_emit(buf, "%d\n", tsdata->report_rate);
+out:
+ mutex_unlock(&tsdata->mutex);
+ return error ?: count;
+}
+
+static int edt_ft5x06_report_rate_set(struct edt_ft5x06_ts_data *tsdata,
+ unsigned int val)
+{
+ if (tsdata->reg_addr.reg_report_rate == NO_REGISTER)
+ return -EOPNOTSUPP;
+
+ if (tsdata->version == EDT_M06)
+ tsdata->report_rate = clamp_val(val, 30, 140);
+ else
+ tsdata->report_rate = clamp_val(val, 1, 255);
+
+ if (val != tsdata->report_rate) {
+ dev_warn(&tsdata->client->dev,
+ "report-rate %dHz is unsupported, use %dHz\n",
+ val, tsdata->report_rate);
+ val = tsdata->report_rate;
+ }
+
+ if (tsdata->version == EDT_M06)
+ val /= 10;
+
+ return regmap_write(tsdata->regmap, tsdata->reg_addr.reg_report_rate,
+ val);
+}
+
+static ssize_t report_rate_store(struct device *dev,
+ struct device_attribute *dattr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
+ unsigned int val;
+ u8 limit_low;
+ u8 limit_high;
+ int error;
+
+ mutex_lock(&tsdata->mutex);
+
+ if (tsdata->factory_mode) {
+ error = -EIO;
+ goto out;
+ }
+
+ error = kstrtouint(buf, 0, &val);
+ if (error)
+ goto out;
+
+ if (tsdata->version == EDT_M06) {
+ limit_low = 30;
+ limit_high = 140;
+ } else {
+ limit_low = 1;
+ limit_high = 255;
+ }
+
+ if (val < limit_low || val > limit_high) {
+ error = -ERANGE;
+ goto out;
+ }
+
+ error = edt_ft5x06_report_rate_set(tsdata, val);
+ if (error) {
+ dev_err(&tsdata->client->dev,
+ "Failed to update attribute %s, error: %d\n",
+ dattr->attr.name, error);
+ goto out;
+ }
+
+out:
+ mutex_unlock(&tsdata->mutex);
+ return error ?: count;
+}
+
+static DEVICE_ATTR_RW(report_rate);
static ssize_t model_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -572,7 +699,7 @@ static struct attribute *edt_ft5x06_attrs[] = {
&edt_ft5x06_attr_offset_x.dattr.attr,
&edt_ft5x06_attr_offset_y.dattr.attr,
&edt_ft5x06_attr_threshold.dattr.attr,
- &edt_ft5x06_attr_report_rate.dattr.attr,
+ &dev_attr_report_rate.attr,
&dev_attr_model.attr,
&dev_attr_fw_version.attr,
&dev_attr_header_errors.attr,
@@ -595,8 +722,7 @@ static void edt_ft5x06_restore_reg_parameters(struct edt_ft5x06_ts_data *tsdata)
if (reg_addr->reg_offset_y != NO_REGISTER)
regmap_write(regmap, reg_addr->reg_offset_y, tsdata->offset_y);
if (reg_addr->reg_report_rate != NO_REGISTER)
- regmap_write(regmap, reg_addr->reg_report_rate,
- tsdata->report_rate);
+ edt_ft5x06_report_rate_set(tsdata, tsdata->report_rate);
}
#ifdef CONFIG_DEBUG_FS
@@ -1029,8 +1155,8 @@ static void edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data *tsdata)
if (reg_addr->reg_offset_y != NO_REGISTER)
regmap_read(regmap, reg_addr->reg_offset_y, &tsdata->offset_y);
if (reg_addr->reg_report_rate != NO_REGISTER)
- regmap_read(regmap, reg_addr->reg_report_rate,
- &tsdata->report_rate);
+ edt_ft5x06_report_rate_get(tsdata);
+
tsdata->num_x = EDT_DEFAULT_NUM_X;
if (reg_addr->reg_num_x != NO_REGISTER) {
if (!regmap_read(regmap, reg_addr->reg_num_x, &val))
@@ -1289,21 +1415,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client)
if (tsdata->reg_addr.reg_report_rate != NO_REGISTER &&
!device_property_read_u32(&client->dev,
"report-rate-hz", &report_rate)) {
- if (tsdata->version == EDT_M06)
- tsdata->report_rate = clamp_val(report_rate, 30, 140);
- else
- tsdata->report_rate = clamp_val(report_rate, 1, 255);
-
- if (report_rate != tsdata->report_rate)
- dev_warn(&client->dev,
- "report-rate %dHz is unsupported, use %dHz\n",
- report_rate, tsdata->report_rate);
-
- if (tsdata->version == EDT_M06)
- tsdata->report_rate /= 10;
-
- regmap_write(tsdata->regmap, tsdata->reg_addr.reg_report_rate,
- tsdata->report_rate);
+ edt_ft5x06_report_rate_set(tsdata, report_rate);
}
dev_dbg(&client->dev,