]> rtime.felk.cvut.cz Git - linux-imx.git/blobdiff - drivers/video/ssd1307fb.c
video: ssd1307fb: Rework the communication functions
[linux-imx.git] / drivers / video / ssd1307fb.c
index a0d6f96ec4e4bca3723643745d5e98bca381668d..9daf058917a7522aab15a3387bec9fa0b71656a4 100644 (file)
@@ -51,6 +51,11 @@ struct ssd1307fb_par {
        u32 width;
 };
 
+struct ssd1307fb_array {
+       u8      type;
+       u8      data[0];
+};
+
 static struct fb_fix_screeninfo ssd1307fb_fix = {
        .id             = "Solomon SSD1307",
        .type           = FB_TYPE_PACKED_PIXELS,
@@ -65,49 +70,67 @@ static struct fb_var_screeninfo ssd1307fb_var = {
        .bits_per_pixel = 1,
 };
 
-static int ssd1307fb_write_array(struct i2c_client *client, u8 type, u8 *cmd, u32 len)
+static struct ssd1307fb_array *ssd1307fb_alloc_array(u32 len, u8 type)
 {
-       u8 *buf;
-       int ret = 0;
-
-       buf = kzalloc(len + 1, GFP_KERNEL);
-       if (!buf) {
-               dev_err(&client->dev, "Couldn't allocate sending buffer.\n");
-               return -ENOMEM;
-       }
+       struct ssd1307fb_array *array;
 
-       buf[0] = type;
-       memcpy(buf + 1, cmd, len);
+       array = kzalloc(sizeof(struct ssd1307fb_array) + len, GFP_KERNEL);
+       if (!array)
+               return NULL;
 
-       ret = i2c_master_send(client, buf, len + 1);
-       if (ret != len + 1) {
-               dev_err(&client->dev, "Couldn't send I2C command.\n");
-               goto error;
-       }
+       array->type = type;
 
-error:
-       kfree(buf);
-       return ret;
+       return array;
 }
 
-static inline int ssd1307fb_write_cmd_array(struct i2c_client *client, u8 *cmd, u32 len)
+static int ssd1307fb_write_array(struct i2c_client *client,
+                                struct ssd1307fb_array *array, u32 len)
 {
-       return ssd1307fb_write_array(client, SSD1307FB_COMMAND, cmd, len);
+       int ret;
+
+       len += sizeof(struct ssd1307fb_array);
+
+       ret = i2c_master_send(client, (u8 *)array, len);
+       if (ret != len) {
+               dev_err(&client->dev, "Couldn't send I2C command.\n");
+               return ret;
+       }
+
+       return 0;
 }
 
 static inline int ssd1307fb_write_cmd(struct i2c_client *client, u8 cmd)
 {
-       return ssd1307fb_write_cmd_array(client, &cmd, 1);
-}
+       struct ssd1307fb_array *array;
+       int ret;
 
-static inline int ssd1307fb_write_data_array(struct i2c_client *client, u8 *cmd, u32 len)
-{
-       return ssd1307fb_write_array(client, SSD1307FB_DATA, cmd, len);
+       array = ssd1307fb_alloc_array(1, SSD1307FB_COMMAND);
+       if (!array)
+               return -ENOMEM;
+
+       array->data[0] = cmd;
+
+       ret = ssd1307fb_write_array(client, array, 1);
+       kfree(array);
+
+       return ret;
 }
 
 static inline int ssd1307fb_write_data(struct i2c_client *client, u8 data)
 {
-       return ssd1307fb_write_data_array(client, &data, 1);
+       struct ssd1307fb_array *array;
+       int ret;
+
+       array = ssd1307fb_alloc_array(1, SSD1307FB_DATA);
+       if (!array)
+               return -ENOMEM;
+
+       array->data[0] = data;
+
+       ret = ssd1307fb_write_array(client, array, 1);
+       kfree(array);
+
+       return ret;
 }
 
 static void ssd1307fb_update_display(struct ssd1307fb_par *par)