From patchwork Thu May 23 08:03:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Courbot X-Patchwork-Id: 2605121 Return-Path: X-Original-To: patchwork-linux-fbdev@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 3A206DFB78 for ; Thu, 23 May 2013 08:09:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751438Ab3EWIJF (ORCPT ); Thu, 23 May 2013 04:09:05 -0400 Received: from hqemgate16.nvidia.com ([216.228.121.65]:3772 "EHLO hqemgate16.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751400Ab3EWII7 (ORCPT ); Thu, 23 May 2013 04:08:59 -0400 X-Greylist: delayed 300 seconds by postgrey-1.27 at vger.kernel.org; Thu, 23 May 2013 04:08:59 EDT Received: from hqnvupgp08.nvidia.com (Not Verified[216.228.121.13]) by hqemgate16.nvidia.com id ; Thu, 23 May 2013 01:03:55 -0700 Received: from hqemhub01.nvidia.com ([172.20.12.94]) by hqnvupgp08.nvidia.com (PGP Universal service); Thu, 23 May 2013 01:03:58 -0700 X-PGP-Universal: processed; by hqnvupgp08.nvidia.com on Thu, 23 May 2013 01:03:58 -0700 Received: from percival.nvidia.com (172.20.144.16) by hqemhub01.nvidia.com (172.20.150.30) with Microsoft SMTP Server (TLS) id 8.3.298.1; Thu, 23 May 2013 01:03:57 -0700 From: Alexandre Courbot To: Stephen Warren , Andrew Morton CC: , , , Alexandre Courbot Subject: [PATCH] video: simplefb: add mode parsing function Date: Thu, 23 May 2013 17:03:51 +0900 Message-ID: <1369296231-26597-1-git-send-email-acourbot@nvidia.com> X-Mailer: git-send-email 1.8.2.3 X-NVConfidentiality: public MIME-Version: 1.0 Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org The naming scheme of simplefb's mode is precise enough to allow building the mode structure from it instead of using a static list of modes. This patch introduces a function that does this. In case exotic modes that cannot be represented from their name alone are needed, the static list of modes is still available as a backup. Signed-off-by: Alexandre Courbot --- Stephen, please note that the "r5g6b5" mode initially supported by the driver becomes "b5g6r5" with the new function. This is because the least significant bits are defined first in the string - this makes parsing much easier, notably for modes which do not fill whole bytes (e.g. 15 bit modes). I hope this is not a problem - it's probably better to do the change now while the driver is still new. .../bindings/video/simple-framebuffer.txt | 12 +++- drivers/video/simplefb.c | 66 +++++++++++++++++++++- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/Documentation/devicetree/bindings/video/simple-framebuffer.txt b/Documentation/devicetree/bindings/video/simple-framebuffer.txt index 3ea4605..f933b3d 100644 --- a/Documentation/devicetree/bindings/video/simple-framebuffer.txt +++ b/Documentation/devicetree/bindings/video/simple-framebuffer.txt @@ -10,8 +10,16 @@ Required properties: - width: The width of the framebuffer in pixels. - height: The height of the framebuffer in pixels. - stride: The number of bytes in each line of the framebuffer. -- format: The format of the framebuffer surface. Valid values are: - - r5g6b5 (16-bit pixels, d[15:11]=r, d[10:5]=g, d[4:0]=b). +- format: The format of the framebuffer surface. Described as a sequence of + channel/nbbits pairs, where each pair describes how many bits are used + by a given color channel. Value channels are "r" (red), "g" (green), + "b" (blue) and "a" (alpha). Channels are listed starting in + bit-significance order. For instance, a format named "r5g6b5" describes + a 16-bit format where red is encoded in the 5 less significant bits, + green in the 6 following ones, and blue in the 5 last: + BBBBBGGG GGGRRRRR + ^ ^ + MSB LSB Example: diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c index 8105c3d..1a1be71 100644 --- a/drivers/video/simplefb.c +++ b/drivers/video/simplefb.c @@ -21,6 +21,7 @@ */ #include +#include #include #include #include @@ -82,8 +83,64 @@ struct simplefb_format { struct fb_bitfield transp; }; -struct simplefb_format simplefb_formats[] = { - { "r5g6b5", 16, {11, 5}, {5, 6}, {0, 5}, {0, 0} }, +static struct simplefb_format *simplefb_parse_format(struct device *dev, + const char *str) +{ + struct simplefb_format *format; + unsigned int cpt = 0; + unsigned int i = 0; + + format = devm_kzalloc(dev, sizeof(*format), GFP_KERNEL); + if (!format) + return ERR_PTR(-ENOMEM); + + while (str[i] != 0) { + struct fb_bitfield *field = 0; + char c = str[i++]; + + switch (c) { + case 'r': + case 'R': + field = &format->red; + break; + case 'g': + case 'G': + field = &format->green; + break; + case 'b': + case 'B': + field = &format->blue; + break; + case 'a': + case 'A': + field = &format->transp; + break; + default: + goto error; + } + + c = str[i++]; + if (c == 0 || !isdigit(c)) + goto error; + + field->offset = cpt; + field->length = c - '0'; + + cpt += field->length; + } + + format->bits_per_pixel = ((cpt + 7) / 8) * 8; + format->name = str; + return format; + +error: + dev_err(dev, "Invalid format string\n"); + return ERR_PTR(-EINVAL); +} + +/* if you use exotic modes that simplefb_parse_format cannot decode, you can + specify them here. */ +static struct simplefb_format simplefb_formats[] = { }; struct simplefb_params { @@ -131,7 +188,10 @@ static int simplefb_parse_dt(struct platform_device *pdev, params->format = &simplefb_formats[i]; break; } - if (!params->format) { + if (!params->format) + params->format = simplefb_parse_format(&pdev->dev, format); + + if (!params->format || IS_ERR(params->format)) { dev_err(&pdev->dev, "Invalid format value\n"); return -EINVAL; }