mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-29 14:33:08 +00:00
83d290c56f
When U-Boot started using SPDX tags we were among the early adopters and there weren't a lot of other examples to borrow from. So we picked the area of the file that usually had a full license text and replaced it with an appropriate SPDX-License-Identifier: entry. Since then, the Linux Kernel has adopted SPDX tags and they place it as the very first line in a file (except where shebangs are used, then it's second line) and with slightly different comment styles than us. In part due to community overlap, in part due to better tag visibility and in part for other minor reasons, switch over to that style. This commit changes all instances where we have a single declared license in the tag as both the before and after are identical in tag contents. There's also a few places where I found we did not have a tag and have introduced one. Signed-off-by: Tom Rini <trini@konsulko.com>
197 lines
4 KiB
C
197 lines
4 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Copyright (c) 2013 Google, Inc
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <dm.h>
|
|
#include <errno.h>
|
|
#include <fdtdec.h>
|
|
#include <malloc.h>
|
|
#include <dm-demo.h>
|
|
#include <asm/io.h>
|
|
#include <asm/gpio.h>
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
/* Shape size */
|
|
#define WIDTH 8
|
|
#define HEIGHT 6
|
|
|
|
struct shape_data {
|
|
int num_chars; /* Number of non-space characters output so far */
|
|
struct gpio_desc gpio_desc[8];
|
|
int gpio_count;
|
|
};
|
|
|
|
/* Crazy little function to draw shapes on the console */
|
|
static int shape_hello(struct udevice *dev, int ch)
|
|
{
|
|
const struct dm_demo_pdata *pdata = dev_get_platdata(dev);
|
|
struct shape_data *data = dev_get_priv(dev);
|
|
static const struct shape {
|
|
int start;
|
|
int end;
|
|
int dstart;
|
|
int dend;
|
|
} shapes[3] = {
|
|
{ 0, 1, 0, 1 },
|
|
{ 0, WIDTH, 0, 0 },
|
|
{ HEIGHT / 2 - 1, WIDTH - HEIGHT / 2 + 1, -1, 1},
|
|
};
|
|
struct shape shape;
|
|
unsigned int index;
|
|
int line, pos, inside;
|
|
const char *colour = pdata->colour;
|
|
int first = 0;
|
|
|
|
if (!ch)
|
|
ch = pdata->default_char;
|
|
if (!ch)
|
|
ch = '@';
|
|
|
|
index = (pdata->sides / 2) - 1;
|
|
if (index >= ARRAY_SIZE(shapes))
|
|
return -EIO;
|
|
shape = shapes[index];
|
|
|
|
for (line = 0; line < HEIGHT; line++) {
|
|
first = 1;
|
|
for (pos = 0; pos < WIDTH; pos++) {
|
|
inside = pos >= shape.start && pos < shape.end;
|
|
if (inside) {
|
|
putc(first ? *colour++ : ch);
|
|
data->num_chars++;
|
|
first = 0;
|
|
if (!*colour)
|
|
colour = pdata->colour;
|
|
} else {
|
|
putc(' ');
|
|
}
|
|
}
|
|
putc('\n');
|
|
shape.start += shape.dstart;
|
|
shape.end += shape.dend;
|
|
if (shape.start < 0) {
|
|
shape.dstart = -shape.dstart;
|
|
shape.dend = -shape.dend;
|
|
shape.start += shape.dstart;
|
|
shape.end += shape.dend;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int shape_status(struct udevice *dev, int *status)
|
|
{
|
|
struct shape_data *data = dev_get_priv(dev);
|
|
|
|
*status = data->num_chars;
|
|
return 0;
|
|
}
|
|
|
|
static int set_light(struct udevice *dev, int light)
|
|
{
|
|
struct shape_data *priv = dev_get_priv(dev);
|
|
struct gpio_desc *desc;
|
|
int ret;
|
|
int i;
|
|
|
|
desc = priv->gpio_desc;
|
|
for (i = 0; i < priv->gpio_count; i++, desc++) {
|
|
uint mask = 1 << i;
|
|
|
|
ret = dm_gpio_set_value(desc, light & mask);
|
|
if (ret < 0)
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int get_light(struct udevice *dev)
|
|
{
|
|
struct shape_data *priv = dev_get_priv(dev);
|
|
struct gpio_desc *desc;
|
|
uint value = 0;
|
|
int ret;
|
|
int i;
|
|
|
|
desc = priv->gpio_desc;
|
|
for (i = 0; i < priv->gpio_count; i++, desc++) {
|
|
uint mask = 1 << i;
|
|
|
|
ret = dm_gpio_get_value(desc);
|
|
if (ret < 0)
|
|
return ret;
|
|
if (ret)
|
|
value |= mask;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
static const struct demo_ops shape_ops = {
|
|
.hello = shape_hello,
|
|
.status = shape_status,
|
|
.get_light = get_light,
|
|
.set_light = set_light,
|
|
};
|
|
|
|
static int shape_ofdata_to_platdata(struct udevice *dev)
|
|
{
|
|
struct dm_demo_pdata *pdata = dev_get_platdata(dev);
|
|
int ret;
|
|
|
|
/* Parse the data that is common with all demo devices */
|
|
ret = demo_parse_dt(dev);
|
|
if (ret)
|
|
return ret;
|
|
|
|
/* Parse the data that only we need */
|
|
pdata->default_char = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
|
|
"character", '@');
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int dm_shape_probe(struct udevice *dev)
|
|
{
|
|
struct shape_data *priv = dev_get_priv(dev);
|
|
int ret;
|
|
|
|
ret = gpio_request_list_by_name(dev, "light-gpios", priv->gpio_desc,
|
|
ARRAY_SIZE(priv->gpio_desc),
|
|
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
|
|
if (ret < 0)
|
|
return ret;
|
|
priv->gpio_count = ret;
|
|
debug("%s: %d GPIOs\n", __func__, priv->gpio_count);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int dm_shape_remove(struct udevice *dev)
|
|
{
|
|
struct shape_data *priv = dev_get_priv(dev);
|
|
|
|
return gpio_free_list(dev, priv->gpio_desc, priv->gpio_count);
|
|
}
|
|
|
|
static const struct udevice_id demo_shape_id[] = {
|
|
{ "demo-shape", 0 },
|
|
{ },
|
|
};
|
|
|
|
U_BOOT_DRIVER(demo_shape_drv) = {
|
|
.name = "demo_shape_drv",
|
|
.of_match = demo_shape_id,
|
|
.id = UCLASS_DEMO,
|
|
.ofdata_to_platdata = shape_ofdata_to_platdata,
|
|
.ops = &shape_ops,
|
|
.probe = dm_shape_probe,
|
|
.remove = dm_shape_remove,
|
|
.priv_auto_alloc_size = sizeof(struct shape_data),
|
|
.platdata_auto_alloc_size = sizeof(struct dm_demo_pdata),
|
|
};
|