PRJ_BASE :=$(dir $(lastword $(MAKEFILE_LIST)))
MAKE_DIR=$(PRJ_BASE)/make

OBJS := sony_fpga_netif.o \
        sony_fpga_sysfs.o \
        sony_fpga_ioctl.o \
        sony_fpga_xpt.o   \
        sony_fpga_sis.o   \
        sony_fpga_local_if_i2c.o \
        sony_fpga_main.o

sony_fpga-objs := $(OBJS)
sony_fpga_nogpu-objs := $(OBJS)

ifdef DISABLE_GPU
obj-m := sony_fpga_nogpu.o
MAKEOPT += -DGPU_DISABLE
else
obj-m := sony_fpga.o
endif


KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD       := $(shell pwd)
MODULE    := $(obj-m:.o=.ko)
SRCS      := $(OBJS:.o=.c)
HEADERS   := sony_fpga*.h

CPPFLAGS += -include $(KERNELDIR)/include/generated/autoconf.h

NVIDIA_SRC := nvidia-580.126.09
EXTRA_CFLAGS += -Wall -mavx -mpreferred-stack-boundary=4
# GPU DMAC
EXTRA_CFLAGS += -I /usr/src/$(NVIDIA_SRC)/ $(MAKEOPT)
# DFX
EXTRA_CFLAGS += -DENABLE_DFX

KBUILD_EXTRA_SYMBOLS := /usr/src/$(NVIDIA_SRC)/Module.symvers

SONY_DRIVER_TARGET_DIR := $(DESTDIR)/sony/ulm/drivers
BINDIR := $(DESTDIR)/usr/bin


all:	$(MODULE)
module:	$(MODULE)

$(MODULE):	$(SRCS) $(HEADERS) stm check_file
	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

.PHONY: gpu_disable
gpu_disable:	$(SRCS) $(HEADERS)
	rm -rf *.o
	DISABLE_GPU=y make

install_pre: sony_fpga.ko gpu_disable
	mkdir -p $(BINDIR)
	mkdir -p $(SONY_DRIVER_TARGET_DIR)

install: install_pre
	install -m 644 sony_fpga.ko $(SONY_DRIVER_TARGET_DIR)
	install -m 644 sony_fpga_nogpu.ko $(SONY_DRIVER_TARGET_DIR)
	install sony_fpga_load $(BINDIR)

clean:
	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.symvers *.order *.unsigned

define make_script
cat sony_fpga_cmd.h | perl -anle '\
BEGIN {\
    print "#!/usr/bin/env python3"; \
    print "# -*- coding: utf-8 -*-\n"; \
    print "from ioctl_opt import IOW, IOR, IOWR, IO"; \
    print "import ctypes\n\n"; \
} \
{ \
if ($$_ =~ /^struct .+{/) {\
    $$def = "class $$F[1](ctypes.Structure):\n    _fields_ = [";\
    $$processing = 1;\
    print "$$def";\
} elsif($$processing == 1) {\
    if ($$_ =~ /^};/) {\
        $$processing = 0;\
        print "    ]\n\n";\
    } else {\
        $$F[1] =~ s/;//;\
        $$tag = $$F[1];\
        $$type = $$F[0];\
\
        if ($$type eq 'struct') {\
            $$tag = $$F[2];\
            $$type = $$F[1];\
            if ($$F[1] =~ /\*$$/) {\
                $$F[1] =~ tr/*//d; \
                $$type = "ctypes.POINTER($$F[1])";\
            }\
            $$tag =~ s/;//;\
        }\
        if ($$tag =~ /\[([0-9]+)\]/) {\
            $$index = int($$1);\
            $$tag =~ s/\[.+//;\
        } else {\
            $$index = 0;\
        }\
        if ($$type eq 'uint32_t') {\
            $$type = "ctypes.c_uint";\
        } elsif ($$type eq 'uint64_t') {\
            $$type = "ctypes.c_ulong";\
        } elsif ($$type eq 'uint16_t') {\
            $$type = "ctypes.c_ushort";\
        } elsif ($$type eq 'uint8_t') {\
            $$type = "ctypes.c_ubyte";\
        } elsif ($$type eq 'int8_t') {\
            $$type = "ctypes.c_byte";\
        } elsif ($$type eq 'int16_t') {\
            $$type = "ctypes.c_short";\
        } elsif ($$type eq 'bool') {\
            $$type = "ctypes.c_bool";\
        } elsif ($$type eq "void*") {\
            $$type = "ctypes.c_void_p";\
        } elsif ($$type eq "uint32_t*") {\
            $$type = "ctypes.POINTER(ctypes.c_uint)";\
        }\
        if ($$index > 0) {\
            $$type .= " * $$index";\
        }\
        $$line = "        ('\''$$tag'\'', $$type),";\
        print $$line;\
    }\
}\
}' > $1;
cat sony_fpga_cmd.h | grep SONY_FPGA_IOC_MAGIC | perl -anle '\
shift @F;\
$$tag = shift @F; \
$$def = join(" ", @F);\
\
$$def =~ s/struct //;\
$$def =~ s/_IO/IO/;\
$$def =~ s/__u32/ctypes.c_uint/;\
print "$$tag = $$def";' >> $1
endef

pylib:
	$(call make_script, sony_fpga_driver_py/src/sony_fpga_driver/__init__.py)

.PHONY: doc
doc:
	$(MAKE) -C doc


include $(MAKE_DIR)/coverity.mk
include $(MAKE_DIR)/tool.mk
include $(MAKE_DIR)/rpm.mk

